rsx: Fix upscaled image reconstruction

- Base the upscaling on the real source and not the "attr" parameter.
- In case of reconstruction, the source is much larger than the subslice in "attr"
This commit is contained in:
kd-11 2020-11-29 19:30:55 +03:00 committed by kd-11
parent 67f48ce21c
commit 2aa5c437e8
4 changed files with 31 additions and 63 deletions

View file

@ -2758,48 +2758,24 @@ namespace rsx
} }
} }
if (rsx::get_resolution_scale_percent() != 100)
{
const f32 resolution_scale = rsx::get_resolution_scale();
if (src_is_render_target) if (src_is_render_target)
{ {
if (src_subres.surface->get_surface_width(rsx::surface_metrics::pixels) > g_cfg.video.min_scalable_dimension) const auto surface_width = src_subres.surface->get_surface_width(rsx::surface_metrics::pixels);
{ const auto surface_height = src_subres.surface->get_surface_height(rsx::surface_metrics::pixels);
src_area.x1 = static_cast<u16>(src_area.x1 * resolution_scale); std::tie(src_area.x1, src_area.y1) = rsx::apply_resolution_scale<false>(src_area.x1, src_area.y1, surface_width, surface_height);
src_area.x2 = static_cast<u16>(src_area.x2 * resolution_scale); std::tie(src_area.x2, src_area.y2) = rsx::apply_resolution_scale<true>(src_area.x2, src_area.y2, surface_width, surface_height);
}
if (src_subres.surface->get_surface_height(rsx::surface_metrics::pixels) > g_cfg.video.min_scalable_dimension)
{
src_area.y1 = static_cast<u16>(src_area.y1 * resolution_scale);
src_area.y2 = static_cast<u16>(src_area.y2 * resolution_scale);
}
}
if (dst_is_render_target)
{
if (dst_subres.surface->get_surface_width(rsx::surface_metrics::pixels) > g_cfg.video.min_scalable_dimension)
{
dst_area.x1 = static_cast<u16>(dst_area.x1 * resolution_scale);
dst_area.x2 = static_cast<u16>(dst_area.x2 * resolution_scale);
}
if (dst_subres.surface->get_surface_height(rsx::surface_metrics::pixels) > g_cfg.video.min_scalable_dimension)
{
dst_area.y1 = static_cast<u16>(dst_area.y1 * resolution_scale);
dst_area.y2 = static_cast<u16>(dst_area.y2 * resolution_scale);
}
}
}
if (src_is_render_target)
{
// The resource is of surface type; possibly disabled AA emulation // The resource is of surface type; possibly disabled AA emulation
src_subres.surface->transform_blit_coordinates(rsx::surface_access::transfer, src_area); src_subres.surface->transform_blit_coordinates(rsx::surface_access::transfer, src_area);
} }
if (dst_is_render_target) if (dst_is_render_target)
{ {
const auto surface_width = dst_subres.surface->get_surface_width(rsx::surface_metrics::pixels);
const auto surface_height = dst_subres.surface->get_surface_height(rsx::surface_metrics::pixels);
std::tie(dst_area.x1, dst_area.y1) = rsx::apply_resolution_scale<false>(dst_area.x1, dst_area.y1, surface_width, surface_height);
std::tie(dst_area.x2, dst_area.y2) = rsx::apply_resolution_scale<true>(dst_area.x2, dst_area.y2, surface_width, surface_height);
// The resource is of surface type; possibly disabled AA emulation // The resource is of surface type; possibly disabled AA emulation
dst_subres.surface->transform_blit_coordinates(rsx::surface_access::transfer, dst_area); dst_subres.surface->transform_blit_coordinates(rsx::surface_access::transfer, dst_area);
} }

View file

@ -306,11 +306,12 @@ namespace rsx
const auto h = std::min(section_end, slice_end) - dst_y; const auto h = std::min(section_end, slice_end) - dst_y;
dst_y = (dst_y - slice_begin); dst_y = (dst_y - slice_begin);
const auto [src_width, src_height] = rsx::apply_resolution_scale<true>(section.src_area.width, h, attr.width, attr.height); const auto surface_width = section.surface->get_surface_width(rsx::surface_metrics::pixels);
const auto [dst_width, unused] = rsx::apply_resolution_scale<true>(section.dst_area.width, RSX_SURFACE_DIMENSION_IGNORED, attr.width, RSX_SURFACE_DIMENSION_IGNORED); const auto surface_height = section.surface->get_surface_height(rsx::surface_metrics::pixels);
const auto dst_height = src_height; const auto [src_width, src_height] = rsx::apply_resolution_scale<true>(section.src_area.width, h, surface_width, surface_height);
const auto [dst_width, dst_height] = rsx::apply_resolution_scale<true>(section.dst_area.width, h, attr.width, attr.height);
std::tie(src_x, src_y) = rsx::apply_resolution_scale<false>(src_x, src_y, attr.width, attr.height); std::tie(src_x, src_y) = rsx::apply_resolution_scale<false>(src_x, src_y, surface_width, surface_height);
std::tie(dst_x, dst_y) = rsx::apply_resolution_scale<false>(dst_x, dst_y, attr.width, attr.height); std::tie(dst_x, dst_y) = rsx::apply_resolution_scale<false>(dst_x, dst_y, attr.width, attr.height);
out.push_back out.push_back
@ -515,6 +516,15 @@ namespace rsx
bool is_depth = texptr->is_depth_surface(); bool is_depth = texptr->is_depth_surface();
auto attr2 = attr; auto attr2 = attr;
if (rsx::get_resolution_scale_percent() != 100)
{
const auto [scaled_w, scaled_h] = rsx::apply_resolution_scale<true>(attr.width, attr.height, surface_width, surface_height);
const auto [unused, scaled_slice_h] = rsx::apply_resolution_scale<false>(RSX_SURFACE_DIMENSION_IGNORED, attr.slice_h, surface_width, surface_height);
attr2.width = scaled_w;
attr2.height = scaled_h;
attr2.slice_h = scaled_slice_h;
}
if (const bool gcm_format_is_depth = is_gcm_depth_format(attr2.gcm_format); if (const bool gcm_format_is_depth = is_gcm_depth_format(attr2.gcm_format);
gcm_format_is_depth != is_depth) gcm_format_is_depth != is_depth)
{ {
@ -540,18 +550,13 @@ namespace rsx
} }
if ((surface_is_rop_target && g_cfg.video.strict_rendering_mode) || if ((surface_is_rop_target && g_cfg.video.strict_rendering_mode) ||
attr2.width < surface_width || attr.width < surface_width ||
attr2.height < surface_height || attr.height < surface_height ||
force_convert) force_convert)
{ {
const auto [scaled_w, scaled_h] = rsx::apply_resolution_scale<true>(attr2.width, attr2.height);
const auto format_class = (force_convert) ? classify_format(attr2.gcm_format) : texptr->format_class(); const auto format_class = (force_convert) ? classify_format(attr2.gcm_format) : texptr->format_class();
const auto command = surface_is_rop_target ? deferred_request_command::copy_image_dynamic : deferred_request_command::copy_image_static; const auto command = surface_is_rop_target ? deferred_request_command::copy_image_dynamic : deferred_request_command::copy_image_static;
attr2.width = scaled_w;
attr2.height = scaled_h;
return { texptr->get_surface(rsx::surface_access::read), command, attr2, {}, return { texptr->get_surface(rsx::surface_access::read), command, attr2, {},
texture_upload_context::framebuffer_storage, format_class, scale, texture_upload_context::framebuffer_storage, format_class, scale,
extended_dimension, decoded_remap }; extended_dimension, decoded_remap };
@ -561,8 +566,6 @@ namespace rsx
texptr->format_class(), scale, rsx::texture_dimension_extended::texture_dimension_2d, surface_is_rop_target }; texptr->format_class(), scale, rsx::texture_dimension_extended::texture_dimension_2d, surface_is_rop_target };
} }
const auto [scaled_w, scaled_h] = rsx::apply_resolution_scale<true>(attr2.width, attr2.height);
if (extended_dimension == rsx::texture_dimension_extended::texture_dimension_3d) if (extended_dimension == rsx::texture_dimension_extended::texture_dimension_3d)
{ {
return{ texptr->get_surface(rsx::surface_access::read), deferred_request_command::_3d_unwrap, return{ texptr->get_surface(rsx::surface_access::read), deferred_request_command::_3d_unwrap,
@ -573,9 +576,6 @@ namespace rsx
verify(HERE), extended_dimension == rsx::texture_dimension_extended::texture_dimension_cubemap; verify(HERE), extended_dimension == rsx::texture_dimension_extended::texture_dimension_cubemap;
attr2.width = scaled_w;
attr2.height = scaled_h;
return{ texptr->get_surface(rsx::surface_access::read), deferred_request_command::cubemap_unwrap, return{ texptr->get_surface(rsx::surface_access::read), deferred_request_command::cubemap_unwrap,
attr2, {}, attr2, {},
texture_upload_context::framebuffer_storage, texptr->format_class(), scale, texture_upload_context::framebuffer_storage, texptr->format_class(), scale,

View file

@ -1484,8 +1484,8 @@ namespace rsx
framebuffer_status_valid = true; framebuffer_status_valid = true;
} }
std::tie(region.x1, region.y1) = rsx::apply_resolution_scale<false>(x1, y1); std::tie(region.x1, region.y1) = rsx::apply_resolution_scale<false>(x1, y1, m_framebuffer_layout.width, m_framebuffer_layout.height);
std::tie(region.x2, region.y2) = rsx::apply_resolution_scale<true>(x2, y2); std::tie(region.x2, region.y2) = rsx::apply_resolution_scale<true>(x2, y2, m_framebuffer_layout.width, m_framebuffer_layout.height);
return true; return true;
} }
@ -1767,8 +1767,6 @@ namespace rsx
result.texcoord_control_mask |= u32(method_registers.point_sprite_control_mask()) << 16; result.texcoord_control_mask |= u32(method_registers.point_sprite_control_mask()) << 16;
} }
const auto resolution_scale = rsx::get_resolution_scale();
for (u32 i = 0; i < rsx::limits::fragment_textures_count; ++i) for (u32 i = 0; i < rsx::limits::fragment_textures_count; ++i)
{ {
auto &tex = rsx::method_registers.fragment_textures[i]; auto &tex = rsx::method_registers.fragment_textures[i];

View file

@ -591,15 +591,9 @@ namespace rsx
template <bool clamp = false> template <bool clamp = false>
static inline const std::pair<u16, u16> apply_resolution_scale(u16 width, u16 height, u16 ref_width = 0, u16 ref_height = 0) static inline const std::pair<u16, u16> apply_resolution_scale(u16 width, u16 height, u16 ref_width = 0, u16 ref_height = 0)
{ {
u16 ref; ref_width = (ref_width)? ref_width : width;
if (width > height) [[likely]] ref_height = (ref_height)? ref_height : height;
{ const u16 ref = std::max(ref_width, ref_height);
ref = (ref_width) ? ref_width : width;
}
else
{
ref = (ref_height) ? ref_height : height;
}
if (ref > g_cfg.video.min_scalable_dimension) if (ref > g_cfg.video.min_scalable_dimension)
{ {