UnitTests: Add DSP accelerator tests
Includes DSP accelerator tests for basic behaviour, and everything that was fixed by the PR.
This commit is contained in:
parent
de6e807364
commit
5dae20ea9d
|
@ -2,11 +2,12 @@ add_dolphin_test(MMIOTest MMIOTest.cpp)
|
|||
add_dolphin_test(PageFaultTest PageFaultTest.cpp)
|
||||
add_dolphin_test(CoreTimingTest CoreTimingTest.cpp)
|
||||
|
||||
add_dolphin_test(DSPAcceleratorTest DSP/DSPAcceleratorTest.cpp)
|
||||
add_dolphin_test(DSPAssemblyTest
|
||||
DSP/DSPAssemblyTest.cpp
|
||||
DSP/DSPTestBinary.cpp
|
||||
DSP/DSPTestText.cpp
|
||||
DSP/HermesBinary.cpp
|
||||
)
|
||||
)
|
||||
|
||||
add_dolphin_test(ESFormatsTest IOS/ES/FormatsTest.cpp IOS/ES/TestBinaryData.cpp)
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/DSP/DSPAccelerator.h"
|
||||
|
||||
// Simulated DSP accelerator.
|
||||
class TestAccelerator : public DSP::Accelerator
|
||||
{
|
||||
public:
|
||||
// For convenience.
|
||||
u16 TestRead()
|
||||
{
|
||||
std::array<s16, 16> coefs{};
|
||||
m_accov_raised = false;
|
||||
return Read(coefs.data());
|
||||
}
|
||||
|
||||
bool EndExceptionRaised() const { return m_accov_raised; }
|
||||
protected:
|
||||
void OnEndException() override
|
||||
{
|
||||
EXPECT_TRUE(m_reads_stopped);
|
||||
m_accov_raised = true;
|
||||
}
|
||||
u8 ReadMemory(u32 address) override { return 0; }
|
||||
void WriteMemory(u32 address, u8 value) override {}
|
||||
bool m_accov_raised = false;
|
||||
};
|
||||
|
||||
TEST(DSPAccelerator, Initialization)
|
||||
{
|
||||
TestAccelerator accelerator;
|
||||
accelerator.SetCurrentAddress(0x00000000);
|
||||
accelerator.SetStartAddress(0x00000000);
|
||||
accelerator.SetEndAddress(0x00001000);
|
||||
EXPECT_EQ(accelerator.GetStartAddress(), 0x00000000u);
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), 0x00000000u);
|
||||
EXPECT_EQ(accelerator.GetEndAddress(), 0x00001000u);
|
||||
}
|
||||
|
||||
TEST(DSPAccelerator, SimpleReads)
|
||||
{
|
||||
TestAccelerator accelerator;
|
||||
accelerator.SetCurrentAddress(0x00000000);
|
||||
accelerator.SetStartAddress(0x00000000);
|
||||
accelerator.SetEndAddress(0x00001000);
|
||||
|
||||
for (size_t i = 1; i <= 0xf; ++i)
|
||||
{
|
||||
accelerator.TestRead();
|
||||
EXPECT_FALSE(accelerator.EndExceptionRaised());
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), accelerator.GetStartAddress() + i);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DSPAccelerator, AddressMasking)
|
||||
{
|
||||
TestAccelerator accelerator;
|
||||
|
||||
accelerator.SetCurrentAddress(0x48000000);
|
||||
accelerator.SetStartAddress(0x48000000);
|
||||
accelerator.SetEndAddress(0x48001000);
|
||||
EXPECT_EQ(accelerator.GetStartAddress(), 0x08000000u);
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), 0x08000000u);
|
||||
EXPECT_EQ(accelerator.GetEndAddress(), 0x08001000u);
|
||||
|
||||
accelerator.SetCurrentAddress(0xffffffff);
|
||||
accelerator.SetStartAddress(0xffffffff);
|
||||
accelerator.SetEndAddress(0xffffffff);
|
||||
EXPECT_EQ(accelerator.GetStartAddress(), 0x3fffffffu);
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), 0xbfffffffu);
|
||||
EXPECT_EQ(accelerator.GetEndAddress(), 0x3fffffffu);
|
||||
}
|
||||
|
||||
TEST(DSPAccelerator, PredScaleRegisterMasking)
|
||||
{
|
||||
TestAccelerator accelerator;
|
||||
|
||||
accelerator.SetPredScale(0xbbbb);
|
||||
EXPECT_EQ(accelerator.GetPredScale(), 0x3bu);
|
||||
accelerator.SetPredScale(0xcccc);
|
||||
EXPECT_EQ(accelerator.GetPredScale(), 0x4cu);
|
||||
accelerator.SetPredScale(0xffff);
|
||||
EXPECT_EQ(accelerator.GetPredScale(), 0x7fu);
|
||||
}
|
||||
|
||||
TEST(DSPAccelerator, OverflowBehaviour)
|
||||
{
|
||||
TestAccelerator accelerator;
|
||||
accelerator.SetCurrentAddress(0x00000000);
|
||||
accelerator.SetStartAddress(0x00000000);
|
||||
accelerator.SetEndAddress(0x0000000f);
|
||||
|
||||
for (size_t i = 1; i <= 0xf; ++i)
|
||||
{
|
||||
accelerator.TestRead();
|
||||
EXPECT_FALSE(accelerator.EndExceptionRaised());
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), accelerator.GetStartAddress() + i);
|
||||
}
|
||||
|
||||
accelerator.TestRead();
|
||||
EXPECT_TRUE(accelerator.EndExceptionRaised());
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), accelerator.GetStartAddress());
|
||||
|
||||
// Since an ACCOV has fired, reads are stopped (until the YN2 register is reset),
|
||||
// so the current address shouldn't be updated for this read.
|
||||
accelerator.TestRead();
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), accelerator.GetStartAddress());
|
||||
|
||||
// Simulate a write to YN2, which internally resets the "reads stopped" flag.
|
||||
// After resetting it, reads should work once again.
|
||||
accelerator.SetYn2(0);
|
||||
for (size_t i = 1; i <= 0xf; ++i)
|
||||
{
|
||||
accelerator.TestRead();
|
||||
EXPECT_FALSE(accelerator.EndExceptionRaised());
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), accelerator.GetStartAddress() + i);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DSPAccelerator, OverflowFor16ByteAlignedAddresses)
|
||||
{
|
||||
TestAccelerator accelerator;
|
||||
accelerator.SetCurrentAddress(0x00000000);
|
||||
accelerator.SetStartAddress(0x00000000);
|
||||
accelerator.SetEndAddress(0x00000010);
|
||||
|
||||
for (size_t i = 1; i <= 0xf; ++i)
|
||||
{
|
||||
accelerator.TestRead();
|
||||
EXPECT_FALSE(accelerator.EndExceptionRaised());
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), accelerator.GetStartAddress() + i);
|
||||
}
|
||||
|
||||
accelerator.TestRead();
|
||||
EXPECT_FALSE(accelerator.EndExceptionRaised());
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), accelerator.GetStartAddress() + 1);
|
||||
|
||||
accelerator.TestRead();
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), accelerator.GetStartAddress() + 2);
|
||||
}
|
||||
|
||||
TEST(DSPAccelerator, OverflowForXXXXXXX1Addresses)
|
||||
{
|
||||
TestAccelerator accelerator;
|
||||
accelerator.SetCurrentAddress(0x00000000);
|
||||
accelerator.SetStartAddress(0x00000000);
|
||||
accelerator.SetEndAddress(0x00000011);
|
||||
|
||||
for (size_t i = 1; i <= 0xf; ++i)
|
||||
{
|
||||
accelerator.TestRead();
|
||||
EXPECT_FALSE(accelerator.EndExceptionRaised());
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), accelerator.GetStartAddress() + i);
|
||||
}
|
||||
|
||||
accelerator.TestRead();
|
||||
EXPECT_FALSE(accelerator.EndExceptionRaised());
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), accelerator.GetStartAddress());
|
||||
|
||||
accelerator.TestRead();
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), accelerator.GetStartAddress() + 1);
|
||||
}
|
||||
|
||||
TEST(DSPAccelerator, CurrentAddressSkips)
|
||||
{
|
||||
TestAccelerator accelerator;
|
||||
accelerator.SetCurrentAddress(0x00000000);
|
||||
accelerator.SetStartAddress(0x00000000);
|
||||
accelerator.SetEndAddress(0x00001000);
|
||||
|
||||
for (size_t j = 1; j <= 0xf; ++j)
|
||||
accelerator.TestRead();
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), 0x0000000fu);
|
||||
|
||||
accelerator.TestRead();
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), 0x00000012u);
|
||||
|
||||
accelerator.TestRead();
|
||||
EXPECT_EQ(accelerator.GetCurrentAddress(), 0x00000013u);
|
||||
}
|
Loading…
Reference in New Issue