rsx: Fix 2D intersection tests

This commit is contained in:
kd-11 2022-08-14 19:46:25 +03:00 committed by kd-11
parent 1244044647
commit bacf518189
3 changed files with 30 additions and 34 deletions

View File

@ -546,20 +546,15 @@ namespace rsx
const auto parent_w = surface->template get_surface_width<rsx::surface_metrics::bytes>();
const auto parent_h = surface->template get_surface_height<rsx::surface_metrics::bytes>();
const auto rect = rsx::intersect_region(surface->base_addr, parent_w, parent_h, 1, base_addr, child_w, child_h, 1, get_rsx_pitch());
const auto src_offset = std::get<0>(rect);
const auto dst_offset = std::get<1>(rect);
const auto size = std::get<2>(rect);
const auto [src_offset, dst_offset, size] = rsx::intersect_region(surface->base_addr, parent_w, parent_h, 1, base_addr, child_w, child_h, 1, get_rsx_pitch());
if (src_offset.x >= parent_w || src_offset.y >= parent_h)
if (!size.width || !size.height)
{
return surface_inheritance_result::none;
}
if (dst_offset.x >= child_w || dst_offset.y >= child_h)
{
return surface_inheritance_result::none;
}
ensure(src_offset.x < parent_w && src_offset.y < parent_h);
ensure(dst_offset.x < child_w && dst_offset.y < child_h);
// TODO: Eventually need to stack all the overlapping regions, but for now just do the latest rect in the space
deferred_clipped_region<T*> region;

View File

@ -332,24 +332,25 @@ namespace rsx
const auto section_bpp = get_format_block_size_in_bytes(section->get_gcm_format());
const auto normalized_width = (section->get_width() * section_bpp) / attr.bpp;
const auto clipped = rsx::intersect_region(
const auto [src_offset, dst_offset, dst_size] = rsx::intersect_region(
section->get_section_base(), normalized_width, section->get_height(), section_bpp, /* parent region (extractee) */
address, attr.width, attr.slice_h, attr.bpp, /* child region (extracted) */
attr.pitch);
// Rect intersection test
// TODO: Make the intersection code cleaner with proper 2D regions
if (std::get<0>(clipped).x >= section->get_width())
if (!dst_size.width || !dst_size.height)
{
// Overlap lies outside the image area!
// Out of bounds, invalid intersection
return;
}
ensure(src_offset.x < normalized_width && src_offset.y < section->get_height());
ensure(dst_offset.x < attr.width && dst_offset.y < attr.slice_h);
const u32 slice_begin = slice * attr.slice_h;
const u32 slice_end = slice_begin + attr.height;
const auto dst_y = std::get<1>(clipped).y;
const auto dst_h = std::get<2>(clipped).height;
const auto dst_y = dst_offset.y;
const auto dst_h = dst_size.height;
const auto section_end = dst_y + dst_h;
if (dst_y >= slice_end || section_end <= slice_begin)
@ -358,14 +359,14 @@ namespace rsx
return;
}
const u16 dst_w = static_cast<u16>(std::get<2>(clipped).width);
const u16 dst_w = static_cast<u16>(dst_size.width);
const u16 src_w = static_cast<u16>(dst_w * attr.bpp) / section_bpp;
const u16 height = std::min(slice_end, section_end) - dst_y;
if (scaling)
{
// Since output is upscaled, also upscale on dst
const auto [_dst_x, _dst_y] = rsx::apply_resolution_scale<false>(static_cast<u16>(std::get<1>(clipped).x), static_cast<u16>(dst_y - slice_begin), attr.width, attr.height);
const auto [_dst_x, _dst_y] = rsx::apply_resolution_scale<false>(static_cast<u16>(dst_offset.x), static_cast<u16>(dst_y - slice_begin), attr.width, attr.height);
const auto [_dst_w, _dst_h] = rsx::apply_resolution_scale<true>(dst_w, height, attr.width, attr.height);
out.push_back
@ -373,16 +374,16 @@ namespace rsx
section->get_raw_texture(),
surface_transform::identity,
0,
static_cast<u16>(std::get<0>(clipped).x), // src.x
static_cast<u16>(std::get<0>(clipped).y), // src.y
_dst_x, // dst.x
_dst_y, // dst.y
static_cast<u16>(src_offset.x), // src.x
static_cast<u16>(src_offset.y), // src.y
_dst_x, // dst.x
_dst_y, // dst.y
slice,
src_w,
height,
_dst_w,
_dst_h,
});
_dst_h
});
}
else
{
@ -391,16 +392,16 @@ namespace rsx
section->get_raw_texture(),
surface_transform::identity,
0,
static_cast<u16>(std::get<0>(clipped).x), // src.x
static_cast<u16>(std::get<0>(clipped).y), // src.y
static_cast<u16>(std::get<1>(clipped).x), // dst.x
static_cast<u16>(dst_y - slice_begin), // dst.y
static_cast<u16>(src_offset.x), // src.x
static_cast<u16>(src_offset.y), // src.y
static_cast<u16>(dst_offset.x), // dst.x
static_cast<u16>(dst_y - slice_begin), // dst.y
0,
src_w,
height,
dst_w,
height,
});
height
});
}
};

View File

@ -570,8 +570,8 @@ namespace rsx
const auto src_y = 0u;
const auto dst_y = (offset / pitch);
const auto dst_x = (offset % pitch) / child_bpp;
const auto w = std::min<u32>(parent_w, child_w - dst_x);
const auto h = std::min<u32>(parent_h, child_h - dst_y);
const auto w = std::min<u32>(parent_w, std::max<u32>(child_w, dst_x) - dst_x); // Clamp negatives to 0!
const auto h = std::min<u32>(parent_h, std::max<u32>(child_h, dst_y) - dst_y);
return std::make_tuple<position2u, position2u, size2u>({ src_x, src_y }, { dst_x, dst_y }, { w, h });
}
@ -582,8 +582,8 @@ namespace rsx
const auto src_x = (offset % pitch) / parent_bpp;
const auto dst_x = 0u;
const auto dst_y = 0u;
const auto w = std::min<u32>(child_w, parent_w - src_x);
const auto h = std::min<u32>(child_h, parent_h - src_y);
const auto w = std::min<u32>(child_w, std::max<u32>(parent_w, src_x) - src_x);
const auto h = std::min<u32>(child_h, std::max<u32>(parent_h, src_y) - src_y);
return std::make_tuple<position2u, position2u, size2u>({ src_x, src_y }, { dst_x, dst_y }, { w, h });
}