Common: Fix rectangle rempty() on ARM32

This commit is contained in:
Stenzek 2024-12-10 16:47:01 +10:00
parent 5767397231
commit e137d3b5c7
No known key found for this signature in database
4 changed files with 72 additions and 10 deletions

View File

@ -78,3 +78,59 @@ TEST(Rectangle, RelationalOperators)
ASSERT_FALSE(r1.eq(r2));
}
TEST(Rectangle, ValidRectangles)
{
static constexpr GSVector4i cases[] = {
GSVector4i::cxpr(1, 2, 3, 4),
GSVector4i::cxpr(-5, -10, -1, -2),
GSVector4i::cxpr(0, 0, 1, 1),
GSVector4i::cxpr(100, 200, 300, 400),
GSVector4i::cxpr(-1000, -2000, 500, 600),
GSVector4i::cxpr(5, 10, 6, 12),
GSVector4i::cxpr(-10, -20, -5, -15),
GSVector4i::cxpr(-5, 0, 5, 10),
GSVector4i::cxpr(-100, -200, 100, 200),
GSVector4i::cxpr(-1, -2, 0, 1),
};
for (GSVector4i tcase : cases)
{
ASSERT_TRUE(tcase.rvalid());
ASSERT_FALSE(tcase.rempty());
}
}
TEST(Rectangle, InvalidRectangles)
{
static constexpr GSVector4i cases[] = {
// left < right but not top < bottom
GSVector4i::cxpr(1, 4, 3, 2),
GSVector4i::cxpr(-5, -2, -1, -10),
GSVector4i::cxpr(0, 1, 1, 0),
GSVector4i::cxpr(100, 400, 300, 200),
GSVector4i::cxpr(-1000, 600, 500, -2000),
GSVector4i::cxpr(5, 12, 6, 10),
GSVector4i::cxpr(-10, -15, -5, -20),
GSVector4i::cxpr(-5, 10, 5, 0),
GSVector4i::cxpr(-100, 200, 100, -200),
GSVector4i::cxpr(-1, 1, 0, -2),
// not left < right but top < bottom
GSVector4i::cxpr(3, 2, 1, 4),
GSVector4i::cxpr(-1, -10, -5, -2),
GSVector4i::cxpr(1, 0, 0, 1),
GSVector4i::cxpr(300, 200, 100, 400),
GSVector4i::cxpr(500, -2000, -1000, 600),
GSVector4i::cxpr(6, 10, 5, 12),
GSVector4i::cxpr(-5, -20, -10, -15),
GSVector4i::cxpr(5, 0, -5, 10),
GSVector4i::cxpr(100, -200, -100, 200),
GSVector4i::cxpr(0, -2, -1, 1),
};
for (GSVector4i tcase : cases)
{
ASSERT_FALSE(tcase.rvalid());
ASSERT_TRUE(tcase.rempty());
}
}

View File

@ -1171,17 +1171,21 @@ public:
ALWAYS_INLINE bool rempty() const
{
#ifdef CPU_ARCH_ARM64
return (vminv_u32(vreinterpret_u32_s32(vget_low_s32(lt32(zwzw())))) == 0);
#else
return (vget_lane_u64(vreinterpret_u64_u32(vreinterpret_u32_s32(vget_low_s32(lt32(zwzw())))), 0) == 0);
#endif
// !any((x, y) < (z, w)) i.e. !not_empty
return (vget_lane_u64(vreinterpret_u64_u32(vclt_s32(vget_low_s32(v4s), vget_high_s32(v4s))), 0) !=
0xFFFFFFFFFFFFFFFFULL);
}
ALWAYS_INLINE bool rvalid() const
{
// !all((x, y) >= (z, w))
return (vget_lane_u64(vreinterpret_u64_u32(vcge_s32(vget_low_s32(v4s), vget_high_s32(v4s))), 0) == 0);
}
ALWAYS_INLINE GSVector4i runion(const GSVector4i& a) const { return min_s32(a).upl64(max_s32(a).srl<8>()); }
ALWAYS_INLINE GSVector4i rintersect(const GSVector4i& a) const { return sat_s32(a); }
ALWAYS_INLINE bool rintersects(const GSVector4i& v) const { return !rintersect(v).rempty(); }
ALWAYS_INLINE bool rintersects(const GSVector4i& v) const { return rintersect(v).rvalid(); }
ALWAYS_INLINE bool rcontains(const GSVector4i& v) const { return rintersect(v).eq(v); }
ALWAYS_INLINE u32 rgba32() const { return static_cast<u32>(ps32().pu16().extract32<0>()); }

View File

@ -958,7 +958,8 @@ public:
ALWAYS_INLINE s32 width() const { return right - left; }
ALWAYS_INLINE s32 height() const { return bottom - top; }
ALWAYS_INLINE bool rempty() const { return lt32(zwzw()).mask() != 0x00ff; }
ALWAYS_INLINE bool rempty() const { return (lt32(zwzw()).mask() != 0x00ff); }
ALWAYS_INLINE bool rvalid() const { return ((ge32(zwzw()).mask() & 0xff) == 0); }
GSVector4i runion(const GSVector4i& v) const
{
@ -966,7 +967,7 @@ public:
}
ALWAYS_INLINE GSVector4i rintersect(const GSVector4i& v) const { return sat_s32(v); }
ALWAYS_INLINE bool rintersects(const GSVector4i& v) const { return !rintersect(v).rempty(); }
ALWAYS_INLINE bool rintersects(const GSVector4i& v) const { return rintersect(v).rvalid(); }
ALWAYS_INLINE bool rcontains(const GSVector4i& v) const { return rintersect(v).eq(v); }
ALWAYS_INLINE u32 rgba32() const { return static_cast<u32>(ps32().pu16().extract32<0>()); }

View File

@ -1071,12 +1071,13 @@ public:
ALWAYS_INLINE s32 width() const { return right - left; }
ALWAYS_INLINE s32 height() const { return bottom - top; }
ALWAYS_INLINE bool rempty() const { return lt32(zwzw()).mask() != 0x00ff; }
ALWAYS_INLINE bool rempty() const { return (lt32(zwzw()).mask() != 0x00ff); }
ALWAYS_INLINE bool rvalid() const { return ((ge32(zwzw()).mask() & 0xff) == 0); }
ALWAYS_INLINE GSVector4i runion(const GSVector4i& v) const { return min_s32(v).blend32<0xc>(max_s32(v)); }
ALWAYS_INLINE GSVector4i rintersect(const GSVector4i& v) const { return sat_s32(v); }
ALWAYS_INLINE bool rintersects(const GSVector4i& v) const { return !rintersect(v).rempty(); }
ALWAYS_INLINE bool rintersects(const GSVector4i& v) const { return rintersect(v).rvalid(); }
ALWAYS_INLINE bool rcontains(const GSVector4i& v) const { return rintersect(v).eq(v); }
ALWAYS_INLINE u32 rgba32() const { return static_cast<u32>(ps32().pu16().extract32<0>()); }