summaryrefslogtreecommitdiff
path: root/src/tests/common/scratch_buffer.cpp
diff options
context:
space:
mode:
authorGravatar Fernando S2022-12-24 20:26:06 -0500
committerGravatar GitHub2022-12-24 20:26:06 -0500
commit3e6850f00bdd541202a8369438bda7988c8001f5 (patch)
tree34691ecb826bc402f68a075de07f4f6aaebf8c44 /src/tests/common/scratch_buffer.cpp
parentqt: fix 'Pause' menu item (#9497) (diff)
parentscratch_buffer: Explicitly defing resize and resize_destructive functions (diff)
downloadyuzu-3e6850f00bdd541202a8369438bda7988c8001f5.tar.gz
yuzu-3e6850f00bdd541202a8369438bda7988c8001f5.tar.xz
yuzu-3e6850f00bdd541202a8369438bda7988c8001f5.zip
Merge pull request #9453 from ameerj/scratch-vector
common: Add ScratchBuffer Class
Diffstat (limited to 'src/tests/common/scratch_buffer.cpp')
-rw-r--r--src/tests/common/scratch_buffer.cpp199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/tests/common/scratch_buffer.cpp b/src/tests/common/scratch_buffer.cpp
new file mode 100644
index 000000000..b602c8d0a
--- /dev/null
+++ b/src/tests/common/scratch_buffer.cpp
@@ -0,0 +1,199 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <algorithm>
5#include <array>
6#include <span>
7#include <catch2/catch.hpp>
8#include "common/common_types.h"
9#include "common/scratch_buffer.h"
10
11namespace Common {
12
13TEST_CASE("ScratchBuffer: Basic Test", "[common]") {
14 ScratchBuffer<u8> buf;
15
16 REQUIRE(buf.size() == 0U);
17 REQUIRE(buf.capacity() == 0U);
18
19 std::array<u8, 10> payload;
20 payload.fill(66);
21
22 buf.resize(payload.size());
23 REQUIRE(buf.size() == payload.size());
24 REQUIRE(buf.capacity() == payload.size());
25
26 std::memcpy(buf.data(), payload.data(), payload.size());
27 for (size_t i = 0; i < payload.size(); ++i) {
28 REQUIRE(buf[i] == payload[i]);
29 }
30}
31
32TEST_CASE("ScratchBuffer: resize_destructive Grow", "[common]") {
33 std::array<u8, 10> payload;
34 payload.fill(66);
35
36 ScratchBuffer<u8> buf(payload.size());
37 REQUIRE(buf.size() == payload.size());
38 REQUIRE(buf.capacity() == payload.size());
39
40 // Increasing the size should reallocate the buffer
41 buf.resize_destructive(payload.size() * 2);
42 REQUIRE(buf.size() == payload.size() * 2);
43 REQUIRE(buf.capacity() == payload.size() * 2);
44
45 // Since the buffer is not value initialized, reading its data will be garbage
46}
47
48TEST_CASE("ScratchBuffer: resize_destructive Shrink", "[common]") {
49 std::array<u8, 10> payload;
50 payload.fill(66);
51
52 ScratchBuffer<u8> buf(payload.size());
53 REQUIRE(buf.size() == payload.size());
54 REQUIRE(buf.capacity() == payload.size());
55
56 std::memcpy(buf.data(), payload.data(), payload.size());
57 for (size_t i = 0; i < payload.size(); ++i) {
58 REQUIRE(buf[i] == payload[i]);
59 }
60
61 // Decreasing the size should not cause a buffer reallocation
62 // This can be tested by ensuring the buffer capacity and data has not changed,
63 buf.resize_destructive(1U);
64 REQUIRE(buf.size() == 1U);
65 REQUIRE(buf.capacity() == payload.size());
66
67 for (size_t i = 0; i < payload.size(); ++i) {
68 REQUIRE(buf[i] == payload[i]);
69 }
70}
71
72TEST_CASE("ScratchBuffer: resize Grow u8", "[common]") {
73 std::array<u8, 10> payload;
74 payload.fill(66);
75
76 ScratchBuffer<u8> buf(payload.size());
77 REQUIRE(buf.size() == payload.size());
78 REQUIRE(buf.capacity() == payload.size());
79
80 std::memcpy(buf.data(), payload.data(), payload.size());
81 for (size_t i = 0; i < payload.size(); ++i) {
82 REQUIRE(buf[i] == payload[i]);
83 }
84
85 // Increasing the size should reallocate the buffer
86 buf.resize(payload.size() * 2);
87 REQUIRE(buf.size() == payload.size() * 2);
88 REQUIRE(buf.capacity() == payload.size() * 2);
89
90 // resize() keeps the previous data intact
91 for (size_t i = 0; i < payload.size(); ++i) {
92 REQUIRE(buf[i] == payload[i]);
93 }
94}
95
96TEST_CASE("ScratchBuffer: resize Grow u64", "[common]") {
97 std::array<u64, 10> payload;
98 payload.fill(6666);
99
100 ScratchBuffer<u64> buf(payload.size());
101 REQUIRE(buf.size() == payload.size());
102 REQUIRE(buf.capacity() == payload.size());
103
104 std::memcpy(buf.data(), payload.data(), payload.size() * sizeof(u64));
105 for (size_t i = 0; i < payload.size(); ++i) {
106 REQUIRE(buf[i] == payload[i]);
107 }
108
109 // Increasing the size should reallocate the buffer
110 buf.resize(payload.size() * 2);
111 REQUIRE(buf.size() == payload.size() * 2);
112 REQUIRE(buf.capacity() == payload.size() * 2);
113
114 // resize() keeps the previous data intact
115 for (size_t i = 0; i < payload.size(); ++i) {
116 REQUIRE(buf[i] == payload[i]);
117 }
118}
119
120TEST_CASE("ScratchBuffer: resize Shrink", "[common]") {
121 std::array<u8, 10> payload;
122 payload.fill(66);
123
124 ScratchBuffer<u8> buf(payload.size());
125 REQUIRE(buf.size() == payload.size());
126 REQUIRE(buf.capacity() == payload.size());
127
128 std::memcpy(buf.data(), payload.data(), payload.size());
129 for (size_t i = 0; i < payload.size(); ++i) {
130 REQUIRE(buf[i] == payload[i]);
131 }
132
133 // Decreasing the size should not cause a buffer reallocation
134 // This can be tested by ensuring the buffer capacity and data has not changed,
135 buf.resize(1U);
136 REQUIRE(buf.size() == 1U);
137 REQUIRE(buf.capacity() == payload.size());
138
139 for (size_t i = 0; i < payload.size(); ++i) {
140 REQUIRE(buf[i] == payload[i]);
141 }
142}
143
144TEST_CASE("ScratchBuffer: Span Size", "[common]") {
145 std::array<u8, 10> payload;
146 payload.fill(66);
147
148 ScratchBuffer<u8> buf(payload.size());
149 REQUIRE(buf.size() == payload.size());
150 REQUIRE(buf.capacity() == payload.size());
151
152 std::memcpy(buf.data(), payload.data(), payload.size());
153 for (size_t i = 0; i < payload.size(); ++i) {
154 REQUIRE(buf[i] == payload[i]);
155 }
156
157 buf.resize(3U);
158 REQUIRE(buf.size() == 3U);
159 REQUIRE(buf.capacity() == payload.size());
160
161 const auto buf_span = std::span<u8>(buf);
162 // The span size is the last requested size of the buffer, not its capacity
163 REQUIRE(buf_span.size() == buf.size());
164
165 for (size_t i = 0; i < buf_span.size(); ++i) {
166 REQUIRE(buf_span[i] == buf[i]);
167 REQUIRE(buf_span[i] == payload[i]);
168 }
169}
170
171TEST_CASE("ScratchBuffer: Span Writes", "[common]") {
172 std::array<u8, 10> payload;
173 payload.fill(66);
174
175 ScratchBuffer<u8> buf(payload.size());
176 REQUIRE(buf.size() == payload.size());
177 REQUIRE(buf.capacity() == payload.size());
178
179 std::memcpy(buf.data(), payload.data(), payload.size());
180 for (size_t i = 0; i < payload.size(); ++i) {
181 REQUIRE(buf[i] == payload[i]);
182 }
183
184 buf.resize(3U);
185 REQUIRE(buf.size() == 3U);
186 REQUIRE(buf.capacity() == payload.size());
187
188 const auto buf_span = std::span<u8>(buf);
189 REQUIRE(buf_span.size() == buf.size());
190
191 for (size_t i = 0; i < buf_span.size(); ++i) {
192 const auto new_value = static_cast<u8>(i + 1U);
193 // Writes to a span of the scratch buffer will propogate to the buffer itself
194 buf_span[i] = new_value;
195 REQUIRE(buf[i] == new_value);
196 }
197}
198
199} // namespace Common