mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-06-01 12:15:27 -06:00
rsx: add simple pair and tuple types
This commit is contained in:
parent
5a761c7184
commit
18111ac8bc
@ -188,6 +188,8 @@ if(BUILD_RPCS3_TESTS)
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
tests/test.cpp
|
tests/test.cpp
|
||||||
tests/test_fmt.cpp
|
tests/test_fmt.cpp
|
||||||
|
tests/test_pair.cpp
|
||||||
|
tests/test_tuple.cpp
|
||||||
tests/test_simple_array.cpp
|
tests/test_simple_array.cpp
|
||||||
tests/test_address_range.cpp
|
tests/test_address_range.cpp
|
||||||
)
|
)
|
||||||
|
|||||||
@ -196,7 +196,7 @@ namespace rsx
|
|||||||
if (is_local_storage())
|
if (is_local_storage())
|
||||||
{
|
{
|
||||||
// Switch to heap storage
|
// Switch to heap storage
|
||||||
_data = static_cast<Ty*>(std::malloc(sizeof(Ty) * size));
|
ensure(_data = static_cast<Ty*>(std::malloc(sizeof(Ty) * size)));
|
||||||
std::memcpy(static_cast<void*>(_data), _local_storage, size_bytes());
|
std::memcpy(static_cast<void*>(_data), _local_storage, size_bytes());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "util/asm.hpp"
|
#include "util/asm.hpp"
|
||||||
|
#include "util/pair.hpp"
|
||||||
|
|
||||||
namespace rsx
|
namespace rsx
|
||||||
{
|
{
|
||||||
@ -244,10 +245,9 @@ namespace rsx
|
|||||||
template <bool is_depth_surface>
|
template <bool is_depth_surface>
|
||||||
void intersect_surface_region(command_list_type cmd, u32 address, surface_type new_surface, surface_type prev_surface)
|
void intersect_surface_region(command_list_type cmd, u32 address, surface_type new_surface, surface_type prev_surface)
|
||||||
{
|
{
|
||||||
auto scan_list = [&new_surface, address](const rsx::address_range32& mem_range,
|
auto scan_list = [&new_surface, address](const rsx::address_range32& mem_range, surface_ranged_map& data)
|
||||||
surface_ranged_map& data) -> rsx::simple_array<std::pair<u32, surface_type>>
|
|
||||||
{
|
{
|
||||||
rsx::simple_array<std::pair<u32, surface_type>> result;
|
rsx::simple_array<utils::pair<u32, surface_type>> result;
|
||||||
for (auto it = data.begin_range(mem_range); it != data.end(); ++it)
|
for (auto it = data.begin_range(mem_range); it != data.end(); ++it)
|
||||||
{
|
{
|
||||||
auto surface = Traits::get(it->second);
|
auto surface = Traits::get(it->second);
|
||||||
@ -314,7 +314,7 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rsx::simple_array<std::pair<u32, surface_type>> surface_info;
|
rsx::simple_array<utils::pair<u32, surface_type>> surface_info;
|
||||||
if (list1.empty())
|
if (list1.empty())
|
||||||
{
|
{
|
||||||
surface_info = std::move(list2);
|
surface_info = std::move(list2);
|
||||||
@ -1091,7 +1091,7 @@ namespace rsx
|
|||||||
rsx::simple_array<surface_overlap_info> get_merged_texture_memory_region(commandbuffer_type& cmd, u32 texaddr, u32 required_width, u32 required_height, u32 required_pitch, u8 required_bpp, rsx::surface_access access)
|
rsx::simple_array<surface_overlap_info> get_merged_texture_memory_region(commandbuffer_type& cmd, u32 texaddr, u32 required_width, u32 required_height, u32 required_pitch, u8 required_bpp, rsx::surface_access access)
|
||||||
{
|
{
|
||||||
rsx::simple_array<surface_overlap_info> result;
|
rsx::simple_array<surface_overlap_info> result;
|
||||||
rsx::simple_array<std::pair<u32, bool>> dirty;
|
rsx::simple_array<utils::pair<u32, bool>> dirty;
|
||||||
|
|
||||||
const auto surface_internal_pitch = (required_width * required_bpp);
|
const auto surface_internal_pitch = (required_width * required_bpp);
|
||||||
|
|
||||||
|
|||||||
@ -387,7 +387,7 @@ namespace gl
|
|||||||
allocator.pools[i].flags = 0;
|
allocator.pools[i].flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsx::simple_array<std::pair<int, int>> replacement_map;
|
rsx::simple_array<utils::pair<int, int>> replacement_map;
|
||||||
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
||||||
{
|
{
|
||||||
if (reference_mask & (1 << i))
|
if (reference_mask & (1 << i))
|
||||||
|
|||||||
@ -736,6 +736,8 @@
|
|||||||
<ClInclude Include="Loader\mself.hpp" />
|
<ClInclude Include="Loader\mself.hpp" />
|
||||||
<ClInclude Include="util\atomic.hpp" />
|
<ClInclude Include="util\atomic.hpp" />
|
||||||
<ClInclude Include="util\bless.hpp" />
|
<ClInclude Include="util\bless.hpp" />
|
||||||
|
<ClInclude Include="util\pair.hpp" />
|
||||||
|
<ClInclude Include="util\tuple.hpp" />
|
||||||
<ClInclude Include="util\video_sink.h" />
|
<ClInclude Include="util\video_sink.h" />
|
||||||
<ClInclude Include="util\video_provider.h" />
|
<ClInclude Include="util\video_provider.h" />
|
||||||
<ClInclude Include="util\media_utils.h" />
|
<ClInclude Include="util\media_utils.h" />
|
||||||
|
|||||||
@ -2758,6 +2758,12 @@
|
|||||||
<ClInclude Include="..\Utilities\deferred_op.hpp">
|
<ClInclude Include="..\Utilities\deferred_op.hpp">
|
||||||
<Filter>Utilities</Filter>
|
<Filter>Utilities</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="util\tuple.hpp">
|
||||||
|
<Filter>Utilities</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="util\pair.hpp">
|
||||||
|
<Filter>Utilities</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">
|
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">
|
||||||
|
|||||||
@ -90,6 +90,8 @@
|
|||||||
<ClCompile Include="test_fmt.cpp" />
|
<ClCompile Include="test_fmt.cpp" />
|
||||||
<ClCompile Include="test_simple_array.cpp" />
|
<ClCompile Include="test_simple_array.cpp" />
|
||||||
<ClCompile Include="test_address_range.cpp" />
|
<ClCompile Include="test_address_range.cpp" />
|
||||||
|
<ClCompile Include="test_tuple.cpp" />
|
||||||
|
<ClCompile Include="test_pair.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets" Condition="'$(GTestInstalled)' == 'true'">
|
<ImportGroup Label="ExtensionTargets" Condition="'$(GTestInstalled)' == 'true'">
|
||||||
@ -102,4 +104,4 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Warning Condition="!Exists('$(GTestPath)')" Text="$([System.String]::Format('$(ErrorText)', '$(GTestPath)'))" />
|
<Warning Condition="!Exists('$(GTestPath)')" Text="$([System.String]::Format('$(ErrorText)', '$(GTestPath)'))" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
46
rpcs3/tests/test_pair.cpp
Normal file
46
rpcs3/tests/test_pair.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "util/types.hpp"
|
||||||
|
#include "util/pair.hpp"
|
||||||
|
|
||||||
|
struct some_struct
|
||||||
|
{
|
||||||
|
u64 v {};
|
||||||
|
char s[12] = "Hello World";
|
||||||
|
|
||||||
|
bool operator == (const some_struct& r) const
|
||||||
|
{
|
||||||
|
return v == r.v && std::memcmp(s, r.s, sizeof(s)) == 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(Utils, Pair)
|
||||||
|
{
|
||||||
|
some_struct s {};
|
||||||
|
s.v = 1234;
|
||||||
|
|
||||||
|
utils::pair<int, some_struct> p;
|
||||||
|
EXPECT_EQ(sizeof(p), 32);
|
||||||
|
EXPECT_EQ(p.first, 0);
|
||||||
|
EXPECT_EQ(p.second, some_struct{});
|
||||||
|
|
||||||
|
p = { 666, s };
|
||||||
|
EXPECT_EQ(p.first, 666);
|
||||||
|
EXPECT_EQ(p.second, s);
|
||||||
|
|
||||||
|
const utils::pair<int, some_struct> p1 = p;
|
||||||
|
EXPECT_EQ(p.first, 666);
|
||||||
|
EXPECT_EQ(p.second, s);
|
||||||
|
EXPECT_EQ(p1.first, 666);
|
||||||
|
EXPECT_EQ(p1.second, s);
|
||||||
|
|
||||||
|
utils::pair<int, some_struct> p2 = p1;
|
||||||
|
EXPECT_EQ(p1.first, 666);
|
||||||
|
EXPECT_EQ(p1.second, s);
|
||||||
|
EXPECT_EQ(p2.first, 666);
|
||||||
|
EXPECT_EQ(p2.second, s);
|
||||||
|
|
||||||
|
utils::pair<int, some_struct> p3 = std::move(p);
|
||||||
|
EXPECT_EQ(p3.first, 666);
|
||||||
|
EXPECT_EQ(p3.second, s);
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "util/pair.hpp"
|
||||||
|
|
||||||
#define private public
|
#define private public
|
||||||
#include "Emu/RSX/Common/simple_array.hpp"
|
#include "Emu/RSX/Common/simple_array.hpp"
|
||||||
#undef private
|
#undef private
|
||||||
@ -240,4 +242,29 @@ namespace rsx
|
|||||||
|
|
||||||
EXPECT_EQ(sum, 15);
|
EXPECT_EQ(sum, 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SimpleArray, SimplePair)
|
||||||
|
{
|
||||||
|
struct some_struct
|
||||||
|
{
|
||||||
|
u64 v {};
|
||||||
|
char s[12] = "Hello World";
|
||||||
|
};
|
||||||
|
some_struct s {};
|
||||||
|
|
||||||
|
rsx::simple_array<utils::pair<int, some_struct>> arr;
|
||||||
|
for (int i = 0; i < 5; ++i)
|
||||||
|
{
|
||||||
|
s.v = i;
|
||||||
|
arr.push_back(utils::pair(i, s));
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(arr.size(), 5);
|
||||||
|
for (int i = 0; i < 5; ++i)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(arr[i].first, i);
|
||||||
|
EXPECT_EQ(arr[i].second.v, i);
|
||||||
|
EXPECT_EQ(std::memcmp(arr[i].second.s, "Hello World", sizeof(arr[i].second.s)), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
114
rpcs3/tests/test_tuple.cpp
Normal file
114
rpcs3/tests/test_tuple.cpp
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "util/tuple.hpp"
|
||||||
|
|
||||||
|
struct some_struct
|
||||||
|
{
|
||||||
|
u64 v {};
|
||||||
|
char s[12] = "Hello World";
|
||||||
|
|
||||||
|
bool operator == (const some_struct& r) const
|
||||||
|
{
|
||||||
|
return v == r.v && std::memcmp(s, r.s, sizeof(s)) == 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(Utils, Tuple)
|
||||||
|
{
|
||||||
|
some_struct s {};
|
||||||
|
s.v = 1234;
|
||||||
|
|
||||||
|
utils::tuple t0 = {};
|
||||||
|
EXPECT_EQ(t0.size(), 0);
|
||||||
|
|
||||||
|
utils::tuple<int> t;
|
||||||
|
EXPECT_EQ(sizeof(t), sizeof(int));
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(t.get<0>()), int&>));
|
||||||
|
EXPECT_EQ(t.size(), 1);
|
||||||
|
EXPECT_EQ(t.get<0>(), 0);
|
||||||
|
|
||||||
|
utils::tuple<int> t1 = 2;
|
||||||
|
EXPECT_EQ(sizeof(t1), sizeof(int));
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(t1.get<0>()), int&>));
|
||||||
|
EXPECT_EQ(t1.size(), 1);
|
||||||
|
EXPECT_EQ(t1.get<0>(), 2);
|
||||||
|
t1 = {};
|
||||||
|
EXPECT_EQ(t1.size(), 1);
|
||||||
|
EXPECT_EQ(t1.get<0>(), 0);
|
||||||
|
|
||||||
|
utils::tuple<int, some_struct> t2 = { 2, s };
|
||||||
|
EXPECT_EQ(sizeof(t2), 32);
|
||||||
|
EXPECT_EQ(t2.size(), 2);
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(t2.get<0>()), int&>));
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(t2.get<1>()), some_struct&>));
|
||||||
|
EXPECT_EQ(t2.get<0>(), 2);
|
||||||
|
EXPECT_EQ(t2.get<1>(), s);
|
||||||
|
t2 = {};
|
||||||
|
EXPECT_EQ(t2.size(), 2);
|
||||||
|
EXPECT_EQ(t2.get<0>(), 0);
|
||||||
|
EXPECT_EQ(t2.get<1>(), some_struct{});
|
||||||
|
|
||||||
|
t2.get<0>() = 666;
|
||||||
|
t2.get<1>() = s;
|
||||||
|
EXPECT_EQ(t2.get<0>(), 666);
|
||||||
|
EXPECT_EQ(t2.get<1>(), s);
|
||||||
|
|
||||||
|
utils::tuple<int, some_struct, double> t3 = { 2, s, 1234.0 };
|
||||||
|
EXPECT_EQ(sizeof(t3), 40);
|
||||||
|
EXPECT_EQ(t3.size(), 3);
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(t3.get<0>()), int&>));
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(t3.get<1>()), some_struct&>));
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(t3.get<2>()), double&>));
|
||||||
|
EXPECT_EQ(t3.get<0>(), 2);
|
||||||
|
EXPECT_EQ(t3.get<1>(), s);
|
||||||
|
EXPECT_EQ(t3.get<2>(), 1234.0);
|
||||||
|
t3 = {};
|
||||||
|
EXPECT_EQ(t3.size(), 3);
|
||||||
|
EXPECT_EQ(t3.get<0>(), 0);
|
||||||
|
EXPECT_EQ(t3.get<1>(), some_struct{});
|
||||||
|
EXPECT_EQ(t3.get<2>(), 0.0);
|
||||||
|
|
||||||
|
t3.get<0>() = 666;
|
||||||
|
t3.get<1>() = s;
|
||||||
|
t3.get<2>() = 7.0;
|
||||||
|
EXPECT_EQ(t3.get<0>(), 666);
|
||||||
|
EXPECT_EQ(t3.get<1>(), s);
|
||||||
|
EXPECT_EQ(t3.get<2>(), 7.0);
|
||||||
|
|
||||||
|
// const
|
||||||
|
const utils::tuple<int, some_struct> tc = { 2, s };
|
||||||
|
EXPECT_EQ(tc.size(), 2);
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(tc.get<0>()), const int&>));
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(tc.get<1>()), const some_struct&>));
|
||||||
|
EXPECT_EQ(tc.get<0>(), 2);
|
||||||
|
EXPECT_EQ(tc.get<1>(), s);
|
||||||
|
|
||||||
|
// assignment
|
||||||
|
const utils::tuple<int, some_struct> ta1 = { 2, s };
|
||||||
|
utils::tuple<int, some_struct> ta = ta1;
|
||||||
|
EXPECT_EQ(ta.size(), 2);
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(ta.get<0>()), int&>));
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(ta.get<1>()), some_struct&>));
|
||||||
|
EXPECT_EQ(ta.get<0>(), 2);
|
||||||
|
EXPECT_EQ(ta.get<1>(), s);
|
||||||
|
|
||||||
|
utils::tuple<int, some_struct> ta2 = { 2, s };
|
||||||
|
ta = ta2;
|
||||||
|
EXPECT_EQ(ta.size(), 2);
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(ta.get<0>()), int&>));
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(ta.get<1>()), some_struct&>));
|
||||||
|
EXPECT_EQ(ta.get<0>(), 2);
|
||||||
|
EXPECT_EQ(ta.get<1>(), s);
|
||||||
|
EXPECT_EQ(ta2.size(), 2);
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(ta2.get<0>()), int&>));
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(ta2.get<1>()), some_struct&>));
|
||||||
|
EXPECT_EQ(ta2.get<0>(), 2);
|
||||||
|
EXPECT_EQ(ta2.get<1>(), s);
|
||||||
|
|
||||||
|
ta = std::move(ta2);
|
||||||
|
EXPECT_EQ(ta.size(), 2);
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(ta.get<0>()), int&>));
|
||||||
|
EXPECT_TRUE((std::is_same_v<decltype(ta.get<1>()), some_struct&>));
|
||||||
|
EXPECT_EQ(ta.get<0>(), 2);
|
||||||
|
EXPECT_EQ(ta.get<1>(), s);
|
||||||
|
}
|
||||||
15
rpcs3/util/pair.hpp
Normal file
15
rpcs3/util/pair.hpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace utils
|
||||||
|
{
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
requires std::is_trivially_copyable_v<T1> && std::is_trivially_destructible_v<T1> &&
|
||||||
|
std::is_trivially_copyable_v<T2> && std::is_trivially_destructible_v<T2>
|
||||||
|
struct pair
|
||||||
|
{
|
||||||
|
T1 first {};
|
||||||
|
T2 second {};
|
||||||
|
};
|
||||||
|
}
|
||||||
63
rpcs3/util/tuple.hpp
Normal file
63
rpcs3/util/tuple.hpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.hpp"
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace utils
|
||||||
|
{
|
||||||
|
template <typename... Ts>
|
||||||
|
requires ((std::is_trivially_copyable_v<Ts> && std::is_trivially_destructible_v<Ts>) && ...)
|
||||||
|
struct tuple;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct tuple<>
|
||||||
|
{
|
||||||
|
constexpr tuple() = default;
|
||||||
|
|
||||||
|
static constexpr usz size() noexcept { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Head, typename... Tail>
|
||||||
|
struct tuple<Head, Tail...> : tuple<Tail...>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Head head;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr tuple()
|
||||||
|
: tuple<Tail...>()
|
||||||
|
, head{}
|
||||||
|
{}
|
||||||
|
|
||||||
|
constexpr tuple(Head h, Tail... t)
|
||||||
|
: tuple<Tail...>(std::forward<Tail>(t)...)
|
||||||
|
, head(std::move(h))
|
||||||
|
{}
|
||||||
|
|
||||||
|
static constexpr usz size() noexcept
|
||||||
|
{
|
||||||
|
return 1 + sizeof...(Tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <usz N>
|
||||||
|
requires (N < size())
|
||||||
|
constexpr auto& get()
|
||||||
|
{
|
||||||
|
if constexpr (N == 0)
|
||||||
|
return head;
|
||||||
|
else
|
||||||
|
return tuple<Tail...>::template get<N - 1>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <usz N>
|
||||||
|
requires (N < size())
|
||||||
|
constexpr const auto& get() const
|
||||||
|
{
|
||||||
|
if constexpr (N == 0)
|
||||||
|
return head;
|
||||||
|
else
|
||||||
|
return tuple<Tail...>::template get<N - 1>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user