Compare commits

...

5 Commits

Author SHA1 Message Date
Niel Lebeck
35aa08bd02
Merge e95f5d3766 into 80ea68b13c 2024-11-11 22:12:45 +08:00
JMC47
80ea68b13c
Merge pull request #13183 from Tilka/sync_on_fifo_reset
ProcessorInterface: sync GPU just before PI_FIFO_RESET
2024-11-11 00:38:26 -05:00
Tillmann Karras
fbce737415 ProcessorInterface: sync GPU just before PI_FIFO_RESET
GXAbortFrame() is problematic for Dolphin because it first writes
PI_FIFO_RESET (for which we discard our internal fifo), then disables CP
reads (for which we execute pending commands in the GP fifo in emulated
memory). I don't know whether there is a race condition on hardware, but
there is one for us. Avoid this by also doing a GPU sync here.
2024-11-09 03:29:05 +00:00
Niel Lebeck
e95f5d3766 Add some unit tests for Rectangle::ClampUL 2024-10-22 17:40:10 -07:00
Niel Lebeck
658a740955 Remove the unused Rectangle::ClampLL function
Also tweak the documentation of `ClampUL`, now that there's no
accompanying `ClampLL`.
2024-10-22 17:40:10 -07:00
3 changed files with 61 additions and 13 deletions

View File

@ -112,18 +112,12 @@ struct Rectangle
constexpr T GetWidth() const { return GetDistance(left, right); } constexpr T GetWidth() const { return GetDistance(left, right); }
constexpr T GetHeight() const { return GetDistance(top, bottom); } constexpr T GetHeight() const { return GetDistance(top, bottom); }
// If the rectangle is in a coordinate system with a lower-left origin, use
// this Clamp.
void ClampLL(T x1, T y1, T x2, T y2)
{
left = std::clamp(left, x1, x2);
right = std::clamp(right, x1, x2);
top = std::clamp(top, y2, y1);
bottom = std::clamp(bottom, y2, y1);
}
// If the rectangle is in a coordinate system with an upper-left origin, // Clamp this rectangle to the given rectangle, specified as coordinates in
// use this Clamp. // a coordinate system with an upper-left origin.
//
// REQUIRES: x1 <= x2
// REQUIRES: y1 <= y2
void ClampUL(T x1, T y1, T x2, T y2) void ClampUL(T x1, T y1, T x2, T y2)
{ {
left = std::clamp(left, x1, x2); left = std::clamp(left, x1, x2);

View File

@ -98,6 +98,10 @@ void ProcessorInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
{ {
system.GetGPFifo().ResetGatherPipe(); system.GetGPFifo().ResetGatherPipe();
// Assume that all bytes that made it into the GPU fifo did in fact execute
// before this MMIO write takes effect.
system.GetFifo().SyncGPUForRegisterAccess();
// Call Fifo::ResetVideoBuffer() from the video thread. Since that function // Call Fifo::ResetVideoBuffer() from the video thread. Since that function
// resets various pointers used by the video thread, we can't call it directly // resets various pointers used by the video thread, we can't call it directly
// from the CPU thread, so queue a task to do it instead. In single-core mode, // from the CPU thread, so queue a task to do it instead. In single-core mode,

View File

@ -187,5 +187,55 @@ TEST(MathUtil, RectangleGetHeightUnsigned)
EXPECT_EQ(rect_e.GetHeight(), u32{0xFFFFFFF8}); EXPECT_EQ(rect_e.GetHeight(), u32{0xFFFFFFF8});
} }
// TODO: Add unit test coverage for `Rectangle::ClampUL`. (And consider removing TEST(MathUtil, RectangleClampUL)
// `Rectangle::ClampLL`, which does not have any callers.) {
// Clamp in one direction
MathUtil::Rectangle<int> rect_a(2, 2, 5, 6);
rect_a.ClampUL(3, 1, 6, 7);
EXPECT_EQ(rect_a, MathUtil::Rectangle<int>(3, 2, 5, 6));
MathUtil::Rectangle<int> rect_b(2, 2, 5, 6);
rect_b.ClampUL(1, 3, 6, 7);
EXPECT_EQ(rect_b, MathUtil::Rectangle<int>(2, 3, 5, 6));
MathUtil::Rectangle<int> rect_c(2, 2, 5, 6);
rect_c.ClampUL(1, 1, 4, 7);
EXPECT_EQ(rect_c, MathUtil::Rectangle<int>(2, 2, 4, 6));
MathUtil::Rectangle<int> rect_d(2, 2, 5, 6);
rect_d.ClampUL(1, 1, 6, 5);
EXPECT_EQ(rect_d, MathUtil::Rectangle<int>(2, 2, 5, 5));
// Clamp in two directions
MathUtil::Rectangle<int> rect_e(2, 2, 5, 6);
rect_e.ClampUL(4, 3, 6, 7);
EXPECT_EQ(rect_e, MathUtil::Rectangle<int>(4, 3, 5, 6));
MathUtil::Rectangle<int> rect_f(2, 2, 5, 6);
rect_f.ClampUL(1, 1, 4, 4);
EXPECT_EQ(rect_f, MathUtil::Rectangle<int>(2, 2, 4, 4));
// Given rectangle contains this rectangle
MathUtil::Rectangle<int> rect_g(2, 2, 5, 6);
rect_g.ClampUL(1, 1, 6, 7);
EXPECT_EQ(rect_g, MathUtil::Rectangle<int>(2, 2, 5, 6));
// Given rectangle lies entirely within this rectangle
MathUtil::Rectangle<int> rect_h(2, 2, 5, 6);
rect_h.ClampUL(3, 3, 4, 4);
EXPECT_EQ(rect_h, MathUtil::Rectangle<int>(3, 3, 4, 4));
// Given rectangle exactly matches this rectangle
MathUtil::Rectangle<int> rect_i(2, 2, 5, 6);
rect_i.ClampUL(2, 2, 5, 6);
EXPECT_EQ(rect_i, MathUtil::Rectangle<int>(2, 2, 5, 6));
// Given rectangle does not intersect this rectangle at all
MathUtil::Rectangle<int> rect_j(2, 2, 5, 6);
rect_j.ClampUL(7, 8, 10, 11);
EXPECT_EQ(rect_j, MathUtil::Rectangle<int>(7, 8, 7, 8));
MathUtil::Rectangle<int> rect_k(2, 2, 5, 6);
rect_k.ClampUL(-1, -1, 1, 0);
EXPECT_EQ(rect_k, MathUtil::Rectangle<int>(1, 0, 1, 0));
}