mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
rsx: Fix 2D intersection tests
This commit is contained in:
parent
1244044647
commit
bacf518189
@ -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;
|
||||
|
@ -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
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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 });
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user