mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-28 21:26:07 +00:00
Merge branch 'master' of https://github.com/dolphin-emu/dolphin into dolphin-emu-master
This commit is contained in:
commit
c18016e795
767 changed files with 87644 additions and 70168 deletions
178
Source/UnitTests/Common/Arm64EmitterTest.cpp
Normal file
178
Source/UnitTests/Common/Arm64EmitterTest.cpp
Normal file
|
@ -0,0 +1,178 @@
|
|||
// Copyright 2023 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "Common/Arm64Emitter.h"
|
||||
#include "Common/BitSet.h"
|
||||
#include "Common/BitUtils.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace Arm64Gen;
|
||||
|
||||
namespace
|
||||
{
|
||||
u32 ZeroParameterFunction()
|
||||
{
|
||||
return 123;
|
||||
}
|
||||
|
||||
u32 OneParameterFunction(u64 a)
|
||||
{
|
||||
return a + 23;
|
||||
}
|
||||
|
||||
u32 TwoParameterFunction(u64 a, u64 b)
|
||||
{
|
||||
return a * 10 + b + 3;
|
||||
}
|
||||
|
||||
u32 ThreeParameterFunction(u64 a, u64 b, u64 c)
|
||||
{
|
||||
return a * 10 + b + c / 10;
|
||||
}
|
||||
|
||||
u32 EightParameterFunction(u64 a, u64 b, u64 c, u64 d, u64 e, u64 f, u64 g, u64 h)
|
||||
{
|
||||
return a / 20 + b / 8 + c / 10 + d / 2 + e / 5 - f + g + h / 3;
|
||||
}
|
||||
|
||||
class TestCallFunction : public ARM64CodeBlock
|
||||
{
|
||||
public:
|
||||
TestCallFunction() { AllocCodeSpace(4096); }
|
||||
|
||||
template <typename F>
|
||||
void Emit(F f)
|
||||
{
|
||||
ResetCodePtr();
|
||||
|
||||
m_code_pointer = GetCodePtr();
|
||||
{
|
||||
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
|
||||
|
||||
constexpr BitSet32 link_register{DecodeReg(ARM64Reg::X30)};
|
||||
ABI_PushRegisters(link_register);
|
||||
f();
|
||||
ABI_PopRegisters(link_register);
|
||||
RET();
|
||||
}
|
||||
|
||||
FlushIcacheSection(const_cast<u8*>(m_code_pointer), const_cast<u8*>(GetCodePtr()));
|
||||
}
|
||||
|
||||
void Run()
|
||||
{
|
||||
const u64 actual = Common::BitCast<u64 (*)()>(m_code_pointer)();
|
||||
constexpr u64 expected = 123;
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
|
||||
private:
|
||||
const u8* m_code_pointer = nullptr;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(Arm64Emitter, CallFunction_ZeroParameters)
|
||||
{
|
||||
TestCallFunction test;
|
||||
test.Emit([&] { test.ABI_CallFunction(&ZeroParameterFunction); });
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(Arm64Emitter, CallFunction_OneConstantParameter)
|
||||
{
|
||||
TestCallFunction test;
|
||||
test.Emit([&] { test.ABI_CallFunction(&OneParameterFunction, 100); });
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(Arm64Emitter, CallFunction_OneRegisterParameterNoMov)
|
||||
{
|
||||
TestCallFunction test;
|
||||
test.Emit([&] {
|
||||
test.MOVI2R(ARM64Reg::X0, 100);
|
||||
test.ABI_CallFunction(&OneParameterFunction, ARM64Reg::X0);
|
||||
});
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(Arm64Emitter, CallFunction_OneRegisterParameterMov)
|
||||
{
|
||||
TestCallFunction test;
|
||||
test.Emit([&] {
|
||||
test.MOVI2R(ARM64Reg::X8, 100);
|
||||
test.ABI_CallFunction(&OneParameterFunction, ARM64Reg::X8);
|
||||
});
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(Arm64Emitter, CallFunction_TwoRegistersMixed)
|
||||
{
|
||||
TestCallFunction test;
|
||||
test.Emit([&] {
|
||||
test.MOVI2R(ARM64Reg::X0, 20);
|
||||
test.ABI_CallFunction(&TwoParameterFunction, 10, ARM64Reg::X0);
|
||||
});
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(Arm64Emitter, CallFunction_TwoRegistersCycle)
|
||||
{
|
||||
TestCallFunction test;
|
||||
test.Emit([&] {
|
||||
test.MOVI2R(ARM64Reg::X0, 20);
|
||||
test.MOVI2R(ARM64Reg::X1, 10);
|
||||
test.ABI_CallFunction(&TwoParameterFunction, ARM64Reg::X1, ARM64Reg::X0);
|
||||
});
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(Arm64Emitter, CallFunction_ThreeRegistersMixed)
|
||||
{
|
||||
TestCallFunction test;
|
||||
test.Emit([&] {
|
||||
test.MOVI2R(ARM64Reg::X1, 10);
|
||||
test.MOVI2R(ARM64Reg::X2, 20);
|
||||
test.ABI_CallFunction(&ThreeParameterFunction, ARM64Reg::X1, ARM64Reg::X2, 30);
|
||||
});
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(Arm64Emitter, CallFunction_ThreeRegistersCycle1)
|
||||
{
|
||||
TestCallFunction test;
|
||||
test.Emit([&] {
|
||||
test.MOVI2R(ARM64Reg::X0, 30);
|
||||
test.MOVI2R(ARM64Reg::X1, 10);
|
||||
test.MOVI2R(ARM64Reg::X2, 20);
|
||||
test.ABI_CallFunction(&ThreeParameterFunction, ARM64Reg::X1, ARM64Reg::X2, ARM64Reg::X0);
|
||||
});
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(Arm64Emitter, CallFunction_ThreeRegistersCycle2)
|
||||
{
|
||||
TestCallFunction test;
|
||||
test.Emit([&] {
|
||||
test.MOVI2R(ARM64Reg::X0, 20);
|
||||
test.MOVI2R(ARM64Reg::X1, 30);
|
||||
test.MOVI2R(ARM64Reg::X2, 10);
|
||||
test.ABI_CallFunction(&ThreeParameterFunction, ARM64Reg::X2, ARM64Reg::X0, ARM64Reg::X1);
|
||||
});
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(Arm64Emitter, CallFunction_EightRegistersMixed)
|
||||
{
|
||||
TestCallFunction test;
|
||||
test.Emit([&] {
|
||||
test.MOVI2R(ARM64Reg::X3, 12);
|
||||
test.MOVI2R(ARM64Reg::X4, 23);
|
||||
test.MOVI2R(ARM64Reg::X5, 24);
|
||||
test.MOVI2R(ARM64Reg::X30, 2000);
|
||||
test.ABI_CallFunction(&EightParameterFunction, ARM64Reg::X30, 40, ARM64Reg::X4, ARM64Reg::X5,
|
||||
ARM64Reg::X4, ARM64Reg::X3, 5, ARM64Reg::X4);
|
||||
});
|
||||
test.Run();
|
||||
}
|
2225
Source/UnitTests/Common/AssemblerTest.cpp
Normal file
2225
Source/UnitTests/Common/AssemblerTest.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,3 +1,4 @@
|
|||
add_dolphin_test(AssemblerTest AssemblerTest.cpp)
|
||||
add_dolphin_test(BitFieldTest BitFieldTest.cpp)
|
||||
add_dolphin_test(BitSetTest BitSetTest.cpp)
|
||||
add_dolphin_test(BitUtilsTest BitUtilsTest.cpp)
|
||||
|
@ -18,7 +19,9 @@ add_dolphin_test(SPSCQueueTest SPSCQueueTest.cpp)
|
|||
add_dolphin_test(StringUtilTest StringUtilTest.cpp)
|
||||
add_dolphin_test(SwapTest SwapTest.cpp)
|
||||
|
||||
if (_M_X86)
|
||||
if (_M_X86_64)
|
||||
add_dolphin_test(x64EmitterTest x64EmitterTest.cpp)
|
||||
target_link_libraries(x64EmitterTest PRIVATE bdisasm)
|
||||
elseif (_M_ARM_64)
|
||||
add_dolphin_test(Arm64EmitterTest Arm64EmitterTest.cpp)
|
||||
endif()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
|
||||
|
@ -9,6 +10,8 @@
|
|||
#include "Common/BitUtils.h"
|
||||
#include "Common/FloatUtils.h"
|
||||
|
||||
#include "../Core/PowerPC/TestValues.h"
|
||||
|
||||
TEST(FloatUtils, IsQNAN)
|
||||
{
|
||||
EXPECT_TRUE(Common::IsQNAN(std::numeric_limits<double>::quiet_NaN()));
|
||||
|
@ -62,3 +65,35 @@ TEST(FloatUtils, FlushToZero)
|
|||
EXPECT_EQ(i_tmp, Common::BitCast<u32>(Common::FlushToZero(Common::BitCast<float>(i_tmp))));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FloatUtils, ApproximateReciprocalSquareRoot)
|
||||
{
|
||||
constexpr std::array<u64, 57> expected_values{
|
||||
0x7FF0'0000'0000'0000, 0x617F'FE80'0000'0000, 0x60BF'FE80'0000'0000, 0x5FE0'0008'2C00'0000,
|
||||
0x5FDF'FE80'0000'0000, 0x5FDF'FE80'0000'0000, 0x3FEF'FE80'0000'0000, 0x1FF0'0008'2C00'0000,
|
||||
0x0000'0000'0000'0000, 0x7FF8'0000'0000'0001, 0x7FFF'FFFF'FFFF'FFFF, 0x7FF8'0000'0000'0000,
|
||||
0x7FFF'FFFF'FFFF'FFFF, 0xFFF0'0000'0000'0000, 0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000,
|
||||
0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000,
|
||||
0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000, 0xFFF8'0000'0000'0001, 0xFFFF'FFFF'FFFF'FFFF,
|
||||
0xFFF8'0000'0000'0000, 0xFFFF'FFFF'FFFF'FFFF, 0x43E6'9FA0'0000'0000, 0x43DF'FE80'0000'0000,
|
||||
0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000, 0x43E6'9360'6000'0000, 0x43DF'ED30'7000'0000,
|
||||
0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000, 0x44A6'9FA0'0000'0000, 0x4496'9FA0'0000'0000,
|
||||
0x448F'FE80'0000'0000, 0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000,
|
||||
0x44A6'9360'6000'0000, 0x4496'9360'6000'0000, 0x448F'ED30'7000'0000, 0x7FF8'0000'0000'0000,
|
||||
0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000, 0x3C06'9FA0'0000'0000, 0x3BFF'FE80'0000'0000,
|
||||
0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000, 0x43EF'FE80'0000'0000, 0x43F6'9FA0'0000'0000,
|
||||
0x7FF8'0000'0000'0000, 0x7FF8'0000'0000'0000, 0x3FEA'2040'0000'0000, 0x3FA0'3108'0000'0000,
|
||||
0x7FF8'0000'0000'0000};
|
||||
|
||||
for (size_t i = 0; i < double_test_values.size(); ++i)
|
||||
{
|
||||
u64 ivalue = double_test_values[i];
|
||||
double dvalue = Common::BitCast<double>(ivalue);
|
||||
|
||||
u64 expected = expected_values[i];
|
||||
|
||||
u64 actual = Common::BitCast<u64>(Common::ApproximateReciprocalSquareRoot(dvalue));
|
||||
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,9 @@ add_dolphin_test(ESFormatsTest IOS/ES/FormatsTest.cpp)
|
|||
|
||||
add_dolphin_test(FileSystemTest IOS/FS/FileSystemTest.cpp)
|
||||
|
||||
if(_M_X86)
|
||||
add_dolphin_test(SkylandersTest IOS/USB/SkylandersTest.cpp)
|
||||
|
||||
if(_M_X86_64)
|
||||
add_dolphin_test(PowerPCTest
|
||||
PowerPC/DivUtilsTest.cpp
|
||||
PowerPC/Jit64Common/ConvertDoubleToSingle.cpp
|
||||
|
|
186
Source/UnitTests/Core/IOS/USB/SkylandersTest.cpp
Normal file
186
Source/UnitTests/Core/IOS/USB/SkylandersTest.cpp
Normal file
|
@ -0,0 +1,186 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include <array>
|
||||
#include <string_view>
|
||||
|
||||
#include "Common/BitUtils.h"
|
||||
#include "Core/IOS/USB/Emulated/Skylanders/SkylanderCrypto.h"
|
||||
#include "Core/IOS/USB/Emulated/Skylanders/SkylanderFigure.h"
|
||||
|
||||
using namespace IOS::HLE::USB::SkylanderCrypto;
|
||||
|
||||
// Figure data generated by:
|
||||
//
|
||||
// const std::string temp_dir = File::CreateTempDir();
|
||||
// IOS::HLE::USB::SkylanderFigure figure(temp_dir + "/test.sky");
|
||||
// figure.Create(0x1D6, 0x3000, std::array<u8, 4>({0x01, 0x23, 0x45, 0x67}));
|
||||
//
|
||||
// IOS::HLE::USB::FigureData data = figure.GetData();
|
||||
// data.skylander_data.money = 5000;
|
||||
// data.skylander_data.hero_level = 50;
|
||||
// data.skylander_data.playtime = 1564894;
|
||||
// const std::u16string nickname = UTF8ToUTF16("Test");
|
||||
// std::memset(data.skylander_data.nickname.data(), 0, data.skylander_data.nickname.size());
|
||||
// std::memcpy(data.skylander_data.nickname.data(), nickname.data(), nickname.size() * 2);
|
||||
// data.skylander_data.last_reset.minute = 5;
|
||||
// data.skylander_data.last_reset.hour = 7;
|
||||
// data.skylander_data.last_reset.day = 11;
|
||||
// data.skylander_data.last_reset.month = 3;
|
||||
// data.skylander_data.last_reset.year = 2020;
|
||||
// data.skylander_data.last_placed.minute = 44;
|
||||
// data.skylander_data.last_placed.hour = 8;
|
||||
// data.skylander_data.last_placed.day = 14;
|
||||
// data.skylander_data.last_placed.month = 4;
|
||||
// data.skylander_data.last_placed.year = 2021;
|
||||
// figure.SetData(&data);
|
||||
//
|
||||
// data.skylander_data.money = 5600;
|
||||
// data.skylander_data.hero_level = 51;
|
||||
// data.skylander_data.playtime = 1764894;
|
||||
// std::memset(data.skylander_data.nickname.data(), 0, data.skylander_data.nickname.size());
|
||||
// std::memcpy(data.skylander_data.nickname.data(), nickname.data(), nickname.size() * 2);
|
||||
// data.skylander_data.last_reset.minute = 5;
|
||||
// data.skylander_data.last_reset.hour = 7;
|
||||
// data.skylander_data.last_reset.day = 11;
|
||||
// data.skylander_data.last_reset.month = 3;
|
||||
// data.skylander_data.last_reset.year = 2020;
|
||||
// data.skylander_data.last_placed.minute = 59;
|
||||
// data.skylander_data.last_placed.hour = 9;
|
||||
// data.skylander_data.last_placed.day = 14;
|
||||
// data.skylander_data.last_placed.month = 4;
|
||||
// data.skylander_data.last_placed.year = 2021;
|
||||
// figure.SetData(&data);
|
||||
//
|
||||
// std::array<u8, IOS::HLE::USB::FIGURE_SIZE> decrypted = {};
|
||||
// figure.DecryptFigure(&decrypted);
|
||||
// File::IOFile f(temp_dir + "/decrypted.sky", "wb");
|
||||
// f.WriteBytes(decrypted.data(), decrypted.size());
|
||||
//
|
||||
static constexpr std::array<u8, IOS::HLE::USB::FIGURE_SIZE> decrypted_figure = {
|
||||
0x01, 0x23, 0x45, 0x67, 0x00, 0x81, 0x01, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xD6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xCB, 0x7D,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x4B, 0x0B, 0x20, 0x10, 0x7C, 0xCB, 0x0F, 0x0F, 0x0F, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3C, 0x98, 0xF9, 0x25, 0xA1, 0x7F, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x88, 0x13, 0xDE, 0xE0, 0x17, 0x00, 0x01, 0x88, 0x3C, 0xC4, 0xE3, 0x76, 0xF9,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1A, 0xF5, 0x2D, 0x76, 0x76, 0xBC, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2C, 0x08, 0x0E, 0x04, 0xE5, 0x07, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x07, 0x0B, 0x03, 0xE4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x89, 0xC3, 0xC7, 0xDF, 0x9D, 0x5D, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x54, 0x5B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xC5, 0x19, 0x6F, 0x78, 0x33, 0xDA, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x56, 0x2F, 0x85, 0xD1, 0xD8, 0x3B, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x70, 0x42, 0x51, 0x82, 0x0F, 0xF8, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xE3, 0x74, 0xBB, 0x2B, 0xE4, 0x19, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7B, 0xC0, 0xEA, 0x64, 0xB9, 0x16, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xE0, 0x15, 0x1E, 0xEE, 0x1A, 0x00, 0x02, 0x03, 0xE7, 0xC4, 0xE3, 0x0F, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xE8, 0xF6, 0x00, 0xCD, 0x52, 0xF7, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3B, 0x09, 0x0E, 0x04, 0xE5, 0x07, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x07, 0x0B, 0x03, 0xE4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xCE, 0x9B, 0xD4, 0x9E, 0x85, 0x34, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0xD7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x5D, 0xAD, 0x3E, 0x37, 0x6E, 0xD5, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x77, 0x96, 0x90, 0xC0, 0x52, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x82, 0x41, 0x7C, 0x39, 0x2B, 0xB3, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xA4, 0x2C, 0xA8, 0x6A, 0xFC, 0x70, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x37, 0x1A, 0x42, 0xC3, 0x17, 0x91, 0x7F, 0x0F, 0x08, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
// Can be assumed to also mean ComputeCRC48 is correct
|
||||
TEST(Skylanders, Keygen)
|
||||
{
|
||||
struct
|
||||
{
|
||||
std::array<u8, 4> nuid;
|
||||
u8 sector;
|
||||
u64 expected;
|
||||
} const inputs[]{{{0x00, 0x00, 0x00, 0x00}, 0, 0x4B0B20107CCB},
|
||||
{{0x94, 0xB0, 0xEE, 0x2D}, 0, 0x4B0B20107CCB},
|
||||
{{0x00, 0x00, 0x00, 0x00}, 11, 0xEA168579FF28},
|
||||
{{0x94, 0xB0, 0xEE, 0x2D}, 1, 0x278e4DA896B5},
|
||||
{{0xF7, 0xDB, 0xFD, 0x5F}, 2, 0x75B9B1F4B9EB}};
|
||||
|
||||
for (auto& test : inputs)
|
||||
{
|
||||
auto actual = CalculateKeyA(test.sector, test.nuid);
|
||||
EXPECT_EQ(test.expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
// Can be assumed to also mean ComputeCRC16 is correct
|
||||
TEST(Skylanders, Checksums)
|
||||
{
|
||||
std::array<u8, 2> actual = {};
|
||||
ComputeChecksumType0(decrypted_figure.data(), actual.data());
|
||||
EXPECT_EQ(Common::BitCastPtr<u16>(decrypted_figure.data() + 0x1E),
|
||||
Common::BitCastPtr<u16>(actual.data()));
|
||||
|
||||
u16 area_offset = 0x80;
|
||||
|
||||
for (u8 i = 0; i < 2; i++)
|
||||
{
|
||||
ComputeChecksumType3(decrypted_figure.data() + area_offset + 0x50, actual.data());
|
||||
EXPECT_EQ(Common::BitCastPtr<u16>(decrypted_figure.data() + area_offset + 0xA),
|
||||
Common::BitCastPtr<u16>(actual.data()));
|
||||
|
||||
ComputeChecksumType2(decrypted_figure.data() + area_offset + 0x10, actual.data());
|
||||
EXPECT_EQ(Common::BitCastPtr<u16>(decrypted_figure.data() + area_offset + 0xC),
|
||||
Common::BitCastPtr<u16>(actual.data()));
|
||||
|
||||
ComputeChecksumType1(decrypted_figure.data() + area_offset, actual.data());
|
||||
EXPECT_EQ(Common::BitCastPtr<u16>(decrypted_figure.data() + area_offset + 0xE),
|
||||
Common::BitCastPtr<u16>(actual.data()));
|
||||
|
||||
area_offset += 0x90;
|
||||
|
||||
ComputeChecksumType6(decrypted_figure.data() + area_offset, actual.data());
|
||||
EXPECT_EQ(Common::BitCastPtr<u16>(decrypted_figure.data() + area_offset),
|
||||
Common::BitCastPtr<u16>(actual.data()));
|
||||
|
||||
area_offset += 0x130;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Skylanders, ToyCode)
|
||||
{
|
||||
const std::array<u8, 11> code_chars = ComputeToyCode(0x14E2CE497CB0B);
|
||||
const std::string_view code_string(reinterpret_cast<const char*>(code_chars.data()),
|
||||
code_chars.size());
|
||||
EXPECT_EQ(code_string, "WCJGC-HHR5Q");
|
||||
}
|
|
@ -84,6 +84,8 @@ TEST(JitArm64, FPRF)
|
|||
const u32 expected_double = RunUpdateFPRF(
|
||||
ppc_state, [&] { ppc_state.UpdateFPRFDouble(Common::BitCast<double>(double_input)); });
|
||||
const u32 actual_double = RunUpdateFPRF(ppc_state, [&] { test.fprf_double(double_input); });
|
||||
if (expected_double != actual_double)
|
||||
fmt::print("{:016x} -> {:08x} == {:08x}\n", double_input, actual_double, expected_double);
|
||||
EXPECT_EQ(expected_double, actual_double);
|
||||
|
||||
const u32 single_input = ConvertToSingle(double_input);
|
||||
|
@ -91,6 +93,8 @@ TEST(JitArm64, FPRF)
|
|||
const u32 expected_single = RunUpdateFPRF(
|
||||
ppc_state, [&] { ppc_state.UpdateFPRFSingle(Common::BitCast<float>(single_input)); });
|
||||
const u32 actual_single = RunUpdateFPRF(ppc_state, [&] { test.fprf_single(single_input); });
|
||||
if (expected_single != actual_single)
|
||||
fmt::print("{:08x} -> {:08x} == {:08x}\n", single_input, actual_single, expected_single);
|
||||
EXPECT_EQ(expected_single, actual_single);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,12 +98,12 @@ TEST(JitArm64, MovI2R_LogImm)
|
|||
for (unsigned rotation = 0; rotation < size; ++rotation)
|
||||
{
|
||||
test.Check64(imm);
|
||||
EXPECT_EQ(static_cast<bool>(LogicalImm(imm, 64)), true);
|
||||
EXPECT_EQ(static_cast<bool>(LogicalImm(imm, GPRSize::B64)), true);
|
||||
|
||||
if (size < 64)
|
||||
{
|
||||
test.Check32(imm);
|
||||
EXPECT_EQ(static_cast<bool>(LogicalImm(static_cast<u32>(imm), 32)), true);
|
||||
EXPECT_EQ(static_cast<bool>(LogicalImm(static_cast<u32>(imm), GPRSize::B32)), true);
|
||||
}
|
||||
|
||||
imm = (imm >> 63) | (imm << 1);
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
<ClCompile Include="Core\DSP\HermesText.cpp" />
|
||||
<ClCompile Include="Core\IOS\ES\FormatsTest.cpp" />
|
||||
<ClCompile Include="Core\IOS\FS\FileSystemTest.cpp" />
|
||||
<ClCompile Include="Core\IOS\USB\SkylandersTest.cpp" />
|
||||
<ClCompile Include="Core\MMIOTest.cpp" />
|
||||
<ClCompile Include="Core\PageFaultTest.cpp" />
|
||||
<ClCompile Include="Core\PowerPC\DivUtilsTest.cpp" />
|
||||
|
@ -80,6 +81,7 @@
|
|||
<ClCompile Include="Core\PowerPC\Jit64Common\Frsqrte.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Platform)'=='ARM64'">
|
||||
<ClCompile Include="Common\Arm64EmitterTest.cpp" />
|
||||
<ClCompile Include="Core\PowerPC\JitArm64\ConvertSingleDouble.cpp" />
|
||||
<ClCompile Include="Core\PowerPC\JitArm64\FPRF.cpp" />
|
||||
<ClCompile Include="Core\PowerPC\JitArm64\Fres.cpp" />
|
||||
|
|
|
@ -759,6 +759,298 @@ TEST_P(VertexLoaderNormalTest, NormalAll)
|
|||
}
|
||||
}
|
||||
|
||||
class VertexLoaderSkippedColorsTest : public VertexLoaderTest,
|
||||
public ::testing::WithParamInterface<std::tuple<bool, bool>>
|
||||
{
|
||||
};
|
||||
INSTANTIATE_TEST_SUITE_P(AllCombinations, VertexLoaderSkippedColorsTest,
|
||||
::testing::Combine(::testing::Values(false, true),
|
||||
::testing::Values(false, true)));
|
||||
|
||||
TEST_P(VertexLoaderSkippedColorsTest, SkippedColors)
|
||||
{
|
||||
bool enable_color_0, enable_color_1;
|
||||
std::tie(enable_color_0, enable_color_1) = GetParam();
|
||||
|
||||
size_t input_size = 1;
|
||||
size_t output_size = 3 * sizeof(float);
|
||||
size_t color_0_offset = 0;
|
||||
size_t color_1_offset = 0;
|
||||
|
||||
m_vtx_desc.low.Position = VertexComponentFormat::Index8;
|
||||
if (enable_color_0)
|
||||
{
|
||||
m_vtx_desc.low.Color0 = VertexComponentFormat::Index8;
|
||||
input_size++;
|
||||
color_0_offset = output_size;
|
||||
output_size += sizeof(u32);
|
||||
}
|
||||
if (enable_color_1)
|
||||
{
|
||||
m_vtx_desc.low.Color1 = VertexComponentFormat::Index8;
|
||||
input_size++;
|
||||
color_1_offset = output_size;
|
||||
output_size += sizeof(u32);
|
||||
}
|
||||
|
||||
m_vtx_attr.g0.PosElements = CoordComponentCount::XYZ;
|
||||
m_vtx_attr.g0.PosFormat = ComponentFormat::Float;
|
||||
m_vtx_attr.g0.Color0Elements = ColorComponentCount::RGBA;
|
||||
m_vtx_attr.g0.Color0Comp = ColorFormat::RGBA8888;
|
||||
m_vtx_attr.g0.Color1Elements = ColorComponentCount::RGBA;
|
||||
m_vtx_attr.g0.Color1Comp = ColorFormat::RGBA8888;
|
||||
|
||||
CreateAndCheckSizes(input_size, output_size);
|
||||
|
||||
// Vertex 0
|
||||
Input<u8>(1);
|
||||
if (enable_color_0)
|
||||
Input<u8>(1);
|
||||
if (enable_color_1)
|
||||
Input<u8>(1);
|
||||
// Vertex 1
|
||||
Input<u8>(0);
|
||||
if (enable_color_0)
|
||||
Input<u8>(0);
|
||||
if (enable_color_1)
|
||||
Input<u8>(0);
|
||||
// Position array
|
||||
VertexLoaderManager::cached_arraybases[CPArray::Position] = m_src.GetPointer();
|
||||
g_main_cp_state.array_strides[CPArray::Position] =
|
||||
sizeof(float); // so 1, 2, 3 for index 0; 2, 3, 4 for index 1
|
||||
Input(1.f);
|
||||
Input(2.f);
|
||||
Input(3.f);
|
||||
Input(4.f);
|
||||
// Color array 0
|
||||
VertexLoaderManager::cached_arraybases[CPArray::Color0] = m_src.GetPointer();
|
||||
g_main_cp_state.array_strides[CPArray::Color0] = sizeof(u32);
|
||||
Input<u32>(0x00010203u);
|
||||
Input<u32>(0x04050607u);
|
||||
// Color array 1
|
||||
VertexLoaderManager::cached_arraybases[CPArray::Color1] = m_src.GetPointer();
|
||||
g_main_cp_state.array_strides[CPArray::Color1] = sizeof(u32);
|
||||
Input<u32>(0x08090a0bu);
|
||||
Input<u32>(0x0c0d0e0fu);
|
||||
|
||||
ASSERT_EQ(m_loader->m_native_vtx_decl.colors[0].enable, enable_color_0);
|
||||
if (enable_color_0)
|
||||
{
|
||||
ASSERT_EQ(m_loader->m_native_vtx_decl.colors[0].offset, color_0_offset);
|
||||
}
|
||||
ASSERT_EQ(m_loader->m_native_vtx_decl.colors[1].enable, enable_color_1);
|
||||
if (enable_color_1)
|
||||
{
|
||||
ASSERT_EQ(m_loader->m_native_vtx_decl.colors[1].offset, color_1_offset);
|
||||
}
|
||||
|
||||
RunVertices(2);
|
||||
// Vertex 0
|
||||
ExpectOut(2);
|
||||
ExpectOut(3);
|
||||
ExpectOut(4);
|
||||
if (enable_color_0)
|
||||
{
|
||||
EXPECT_EQ((m_dst.Read<u32, true>()), 0x04050607u);
|
||||
}
|
||||
if (enable_color_1)
|
||||
{
|
||||
EXPECT_EQ((m_dst.Read<u32, true>()), 0x0c0d0e0fu);
|
||||
}
|
||||
// Vertex 1
|
||||
ExpectOut(1);
|
||||
ExpectOut(2);
|
||||
ExpectOut(3);
|
||||
if (enable_color_0)
|
||||
{
|
||||
EXPECT_EQ((m_dst.Read<u32, true>()), 0x00010203u);
|
||||
}
|
||||
if (enable_color_1)
|
||||
{
|
||||
EXPECT_EQ((m_dst.Read<u32, true>()), 0x08090a0bu);
|
||||
}
|
||||
}
|
||||
|
||||
class VertexLoaderSkippedTexCoordsTest : public VertexLoaderTest,
|
||||
public ::testing::WithParamInterface<u32>
|
||||
{
|
||||
public:
|
||||
static constexpr u32 NUM_COMPONENTS_TO_TEST = 3;
|
||||
static constexpr u32 NUM_PARAMETERS_PER_COMPONENT = 3;
|
||||
static constexpr u32 NUM_COMBINATIONS =
|
||||
1 << (NUM_COMPONENTS_TO_TEST * NUM_PARAMETERS_PER_COMPONENT);
|
||||
};
|
||||
INSTANTIATE_TEST_SUITE_P(AllCombinations, VertexLoaderSkippedTexCoordsTest,
|
||||
::testing::Range(0u, VertexLoaderSkippedTexCoordsTest::NUM_COMBINATIONS));
|
||||
|
||||
TEST_P(VertexLoaderSkippedTexCoordsTest, SkippedTextures)
|
||||
{
|
||||
std::array<bool, NUM_COMPONENTS_TO_TEST> enable_tex, enable_matrix, use_st;
|
||||
const u32 param = GetParam();
|
||||
for (u32 component = 0; component < NUM_COMPONENTS_TO_TEST; component++)
|
||||
{
|
||||
const u32 bits = param >> (component * NUM_PARAMETERS_PER_COMPONENT);
|
||||
enable_tex[component] = (bits & 1);
|
||||
enable_matrix[component] = (bits & 2);
|
||||
use_st[component] = (bits & 4);
|
||||
}
|
||||
|
||||
size_t input_size = 1;
|
||||
size_t output_size = 3 * sizeof(float);
|
||||
|
||||
std::array<bool, NUM_COMPONENTS_TO_TEST> component_enabled{};
|
||||
std::array<size_t, NUM_COMPONENTS_TO_TEST> component_offset{};
|
||||
|
||||
m_vtx_desc.low.Position = VertexComponentFormat::Index8;
|
||||
m_vtx_attr.g0.PosElements = CoordComponentCount::XYZ;
|
||||
m_vtx_attr.g0.PosFormat = ComponentFormat::Float;
|
||||
|
||||
for (size_t i = 0; i < NUM_COMPONENTS_TO_TEST; i++)
|
||||
{
|
||||
if (enable_matrix[i] || enable_tex[i])
|
||||
{
|
||||
component_enabled[i] = true;
|
||||
component_offset[i] = output_size;
|
||||
if (enable_matrix[i])
|
||||
{
|
||||
output_size += 3 * sizeof(float);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (use_st[i])
|
||||
{
|
||||
output_size += 2 * sizeof(float);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_size += sizeof(float);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (enable_matrix[i])
|
||||
{
|
||||
m_vtx_desc.low.TexMatIdx[i] = enable_matrix[i];
|
||||
input_size++;
|
||||
}
|
||||
if (enable_tex[i])
|
||||
{
|
||||
m_vtx_desc.high.TexCoord[i] = VertexComponentFormat::Index8;
|
||||
input_size++;
|
||||
}
|
||||
|
||||
m_vtx_attr.SetTexElements(i, use_st[i] ? TexComponentCount::ST : TexComponentCount::S);
|
||||
m_vtx_attr.SetTexFormat(i, ComponentFormat::Float);
|
||||
m_vtx_attr.SetTexFrac(i, 0);
|
||||
}
|
||||
|
||||
CreateAndCheckSizes(input_size, output_size);
|
||||
|
||||
// Vertex 0
|
||||
for (size_t i = 0; i < NUM_COMPONENTS_TO_TEST; i++)
|
||||
{
|
||||
if (enable_matrix[i])
|
||||
Input<u8>(u8(20 + i));
|
||||
}
|
||||
Input<u8>(1); // Position
|
||||
for (size_t i = 0; i < NUM_COMPONENTS_TO_TEST; i++)
|
||||
{
|
||||
if (enable_tex[i])
|
||||
Input<u8>(1);
|
||||
}
|
||||
// Vertex 1
|
||||
for (size_t i = 0; i < NUM_COMPONENTS_TO_TEST; i++)
|
||||
{
|
||||
if (enable_matrix[i])
|
||||
Input<u8>(u8(10 + i));
|
||||
}
|
||||
Input<u8>(0); // Position
|
||||
for (size_t i = 0; i < NUM_COMPONENTS_TO_TEST; i++)
|
||||
{
|
||||
if (enable_tex[i])
|
||||
Input<u8>(0);
|
||||
}
|
||||
// Position array
|
||||
VertexLoaderManager::cached_arraybases[CPArray::Position] = m_src.GetPointer();
|
||||
g_main_cp_state.array_strides[CPArray::Position] =
|
||||
sizeof(float); // so 1, 2, 3 for index 0; 2, 3, 4 for index 1
|
||||
Input(1.f);
|
||||
Input(2.f);
|
||||
Input(3.f);
|
||||
Input(4.f);
|
||||
// Texture coord arrays
|
||||
for (u8 i = 0; i < NUM_COMPONENTS_TO_TEST; i++)
|
||||
{
|
||||
VertexLoaderManager::cached_arraybases[CPArray::TexCoord0 + i] = m_src.GetPointer();
|
||||
g_main_cp_state.array_strides[CPArray::TexCoord0 + i] = 2 * sizeof(float);
|
||||
Input<float>(i * 100 + 11);
|
||||
Input<float>(i * 100 + 12);
|
||||
Input<float>(i * 100 + 21);
|
||||
Input<float>(i * 100 + 22);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < NUM_COMPONENTS_TO_TEST; i++)
|
||||
{
|
||||
ASSERT_EQ(m_loader->m_native_vtx_decl.texcoords[i].enable, component_enabled[i]);
|
||||
if (component_enabled[i])
|
||||
{
|
||||
ASSERT_EQ(m_loader->m_native_vtx_decl.texcoords[i].offset, component_offset[i]);
|
||||
}
|
||||
}
|
||||
|
||||
RunVertices(2);
|
||||
|
||||
// Vertex 0
|
||||
ExpectOut(2);
|
||||
ExpectOut(3);
|
||||
ExpectOut(4);
|
||||
for (size_t i = 0; i < NUM_COMPONENTS_TO_TEST; i++)
|
||||
{
|
||||
size_t num_read = 0;
|
||||
if (enable_tex[i])
|
||||
{
|
||||
ExpectOut(i * 100 + 21);
|
||||
num_read++;
|
||||
if (use_st[i])
|
||||
{
|
||||
ExpectOut(i * 100 + 22);
|
||||
num_read++;
|
||||
}
|
||||
}
|
||||
if (enable_matrix[i])
|
||||
{
|
||||
// With a matrix there are always 3 components; otherwise-unused components should be 0
|
||||
while (num_read++ < 2)
|
||||
ExpectOut(0);
|
||||
ExpectOut(20 + i);
|
||||
}
|
||||
}
|
||||
// Vertex 1
|
||||
ExpectOut(1);
|
||||
ExpectOut(2);
|
||||
ExpectOut(3);
|
||||
for (size_t i = 0; i < NUM_COMPONENTS_TO_TEST; i++)
|
||||
{
|
||||
size_t num_read = 0;
|
||||
if (enable_tex[i])
|
||||
{
|
||||
ExpectOut(i * 100 + 11);
|
||||
num_read++;
|
||||
if (use_st[i])
|
||||
{
|
||||
ExpectOut(i * 100 + 12);
|
||||
num_read++;
|
||||
}
|
||||
}
|
||||
if (enable_matrix[i])
|
||||
{
|
||||
// With a matrix there are always 3 components; otherwise-unused components should be 0
|
||||
while (num_read++ < 2)
|
||||
ExpectOut(0);
|
||||
ExpectOut(10 + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For gtest, which doesn't know about our fmt::formatters by default
|
||||
static void PrintTo(const VertexComponentFormat& t, std::ostream* os)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue