summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ameerj2022-12-19 22:40:50 -0500
committerGravatar ameerj2022-12-19 22:40:50 -0500
commitc6590ad07b384762fd90ee8852796ec681a69286 (patch)
treec0d8d2d157f3bb4be01331f2da459c0f68ca4d7b /src
parenttests: Add ScratchBuffer tests (diff)
downloadyuzu-c6590ad07b384762fd90ee8852796ec681a69286.tar.gz
yuzu-c6590ad07b384762fd90ee8852796ec681a69286.tar.xz
yuzu-c6590ad07b384762fd90ee8852796ec681a69286.zip
scratch_buffer: Explicitly defing resize and resize_destructive functions
resize keeps previous data intact when the buffer grows resize_destructive destroys the previous data when the buffer grows
Diffstat (limited to 'src')
-rw-r--r--src/common/scratch_buffer.h17
-rw-r--r--src/tests/common/scratch_buffer.cpp78
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h2
-rw-r--r--src/video_core/dma_pusher.cpp2
-rw-r--r--src/video_core/engines/engine_upload.cpp4
-rw-r--r--src/video_core/engines/maxwell_dma.cpp18
-rw-r--r--src/video_core/host1x/vic.cpp6
7 files changed, 108 insertions, 19 deletions
diff --git a/src/common/scratch_buffer.h b/src/common/scratch_buffer.h
index 59bb8a9ea..1245a5086 100644
--- a/src/common/scratch_buffer.h
+++ b/src/common/scratch_buffer.h
@@ -25,8 +25,21 @@ public:
25 ~ScratchBuffer() = default; 25 ~ScratchBuffer() = default;
26 26
27 /// This will only grow the buffer's capacity if size is greater than the current capacity. 27 /// This will only grow the buffer's capacity if size is greater than the current capacity.
28 /// The previously held data will remain intact.
28 void resize(size_t size) { 29 void resize(size_t size) {
29 if (size > buffer_capacity) { 30 if (size > buffer_capacity) {
31 auto new_buffer = Common::make_unique_for_overwrite<T[]>(size);
32 std::move(buffer.get(), buffer.get() + buffer_capacity, new_buffer.get());
33 buffer = std::move(new_buffer);
34 buffer_capacity = size;
35 }
36 last_requested_size = size;
37 }
38
39 /// This will only grow the buffer's capacity if size is greater than the current capacity.
40 /// The previously held data will be destroyed if a reallocation occurs.
41 void resize_destructive(size_t size) {
42 if (size > buffer_capacity) {
30 buffer_capacity = size; 43 buffer_capacity = size;
31 buffer = Common::make_unique_for_overwrite<T[]>(buffer_capacity); 44 buffer = Common::make_unique_for_overwrite<T[]>(buffer_capacity);
32 } 45 }
@@ -61,6 +74,10 @@ public:
61 return buffer[i]; 74 return buffer[i];
62 } 75 }
63 76
77 [[nodiscard]] const T& operator[](size_t i) const {
78 return buffer[i];
79 }
80
64 [[nodiscard]] size_t size() const noexcept { 81 [[nodiscard]] size_t size() const noexcept {
65 return last_requested_size; 82 return last_requested_size;
66 } 83 }
diff --git a/src/tests/common/scratch_buffer.cpp b/src/tests/common/scratch_buffer.cpp
index a59490f55..b602c8d0a 100644
--- a/src/tests/common/scratch_buffer.cpp
+++ b/src/tests/common/scratch_buffer.cpp
@@ -29,7 +29,7 @@ TEST_CASE("ScratchBuffer: Basic Test", "[common]") {
29 } 29 }
30} 30}
31 31
32TEST_CASE("ScratchBuffer: Resize Grow", "[common]") { 32TEST_CASE("ScratchBuffer: resize_destructive Grow", "[common]") {
33 std::array<u8, 10> payload; 33 std::array<u8, 10> payload;
34 payload.fill(66); 34 payload.fill(66);
35 35
@@ -38,14 +38,86 @@ TEST_CASE("ScratchBuffer: Resize Grow", "[common]") {
38 REQUIRE(buf.capacity() == payload.size()); 38 REQUIRE(buf.capacity() == payload.size());
39 39
40 // Increasing the size should reallocate the buffer 40 // Increasing the size should reallocate the buffer
41 buf.resize(payload.size() * 2); 41 buf.resize_destructive(payload.size() * 2);
42 REQUIRE(buf.size() == payload.size() * 2); 42 REQUIRE(buf.size() == payload.size() * 2);
43 REQUIRE(buf.capacity() == payload.size() * 2); 43 REQUIRE(buf.capacity() == payload.size() * 2);
44 44
45 // Since the buffer is not value initialized, reading its data will be garbage 45 // Since the buffer is not value initialized, reading its data will be garbage
46} 46}
47 47
48TEST_CASE("ScratchBuffer: Resize Shrink", "[common]") { 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]") {
49 std::array<u8, 10> payload; 121 std::array<u8, 10> payload;
50 payload.fill(66); 122 payload.fill(66);
51 123
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index a8bd5585b..6c8d98946 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -1926,7 +1926,7 @@ std::span<const u8> BufferCache<P>::ImmediateBufferWithData(VAddr cpu_addr, size
1926 1926
1927template <class P> 1927template <class P>
1928std::span<u8> BufferCache<P>::ImmediateBuffer(size_t wanted_capacity) { 1928std::span<u8> BufferCache<P>::ImmediateBuffer(size_t wanted_capacity) {
1929 immediate_buffer_alloc.resize(wanted_capacity); 1929 immediate_buffer_alloc.resize_destructive(wanted_capacity);
1930 return std::span<u8>(immediate_buffer_alloc.data(), wanted_capacity); 1930 return std::span<u8>(immediate_buffer_alloc.data(), wanted_capacity);
1931} 1931}
1932 1932
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp
index d1f541bf5..322de2606 100644
--- a/src/video_core/dma_pusher.cpp
+++ b/src/video_core/dma_pusher.cpp
@@ -74,7 +74,7 @@ bool DmaPusher::Step() {
74 } 74 }
75 75
76 // Push buffer non-empty, read a word 76 // Push buffer non-empty, read a word
77 command_headers.resize(command_list_header.size); 77 command_headers.resize_destructive(command_list_header.size);
78 if (Settings::IsGPULevelHigh()) { 78 if (Settings::IsGPULevelHigh()) {
79 memory_manager.ReadBlock(dma_get, command_headers.data(), 79 memory_manager.ReadBlock(dma_get, command_headers.data(),
80 command_list_header.size * sizeof(u32)); 80 command_list_header.size * sizeof(u32));
diff --git a/src/video_core/engines/engine_upload.cpp b/src/video_core/engines/engine_upload.cpp
index e4f8331ab..cea1dd8b0 100644
--- a/src/video_core/engines/engine_upload.cpp
+++ b/src/video_core/engines/engine_upload.cpp
@@ -24,7 +24,7 @@ void State::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) {
24void State::ProcessExec(const bool is_linear_) { 24void State::ProcessExec(const bool is_linear_) {
25 write_offset = 0; 25 write_offset = 0;
26 copy_size = regs.line_length_in * regs.line_count; 26 copy_size = regs.line_length_in * regs.line_count;
27 inner_buffer.resize(copy_size); 27 inner_buffer.resize_destructive(copy_size);
28 is_linear = is_linear_; 28 is_linear = is_linear_;
29} 29}
30 30
@@ -70,7 +70,7 @@ void State::ProcessData(std::span<const u8> read_buffer) {
70 const std::size_t dst_size = Tegra::Texture::CalculateSize( 70 const std::size_t dst_size = Tegra::Texture::CalculateSize(
71 true, bytes_per_pixel, width, regs.dest.height, regs.dest.depth, 71 true, bytes_per_pixel, width, regs.dest.height, regs.dest.depth,
72 regs.dest.BlockHeight(), regs.dest.BlockDepth()); 72 regs.dest.BlockHeight(), regs.dest.BlockDepth());
73 tmp_buffer.resize(dst_size); 73 tmp_buffer.resize_destructive(dst_size);
74 memory_manager.ReadBlock(address, tmp_buffer.data(), dst_size); 74 memory_manager.ReadBlock(address, tmp_buffer.data(), dst_size);
75 Tegra::Texture::SwizzleSubrect(tmp_buffer, read_buffer, bytes_per_pixel, width, 75 Tegra::Texture::SwizzleSubrect(tmp_buffer, read_buffer, bytes_per_pixel, width,
76 regs.dest.height, regs.dest.depth, x_offset, regs.dest.y, 76 regs.dest.height, regs.dest.depth, x_offset, regs.dest.y,
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index dc873732e..f73d7bf0f 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -184,8 +184,8 @@ void MaxwellDMA::CopyBlockLinearToPitch() {
184 const size_t src_size = 184 const size_t src_size =
185 CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth); 185 CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth);
186 186
187 read_buffer.resize(src_size); 187 read_buffer.resize_destructive(src_size);
188 write_buffer.resize(dst_size); 188 write_buffer.resize_destructive(dst_size);
189 189
190 memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size); 190 memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size);
191 memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size); 191 memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size);
@@ -231,8 +231,8 @@ void MaxwellDMA::CopyPitchToBlockLinear() {
231 CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth); 231 CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth);
232 const size_t src_size = static_cast<size_t>(regs.pitch_in) * regs.line_count; 232 const size_t src_size = static_cast<size_t>(regs.pitch_in) * regs.line_count;
233 233
234 read_buffer.resize(src_size); 234 read_buffer.resize_destructive(src_size);
235 write_buffer.resize(dst_size); 235 write_buffer.resize_destructive(dst_size);
236 236
237 memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size); 237 memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size);
238 if (Settings::IsGPULevelExtreme()) { 238 if (Settings::IsGPULevelExtreme()) {
@@ -261,8 +261,8 @@ void MaxwellDMA::FastCopyBlockLinearToPitch() {
261 pos_x = pos_x % x_in_gob; 261 pos_x = pos_x % x_in_gob;
262 pos_y = pos_y % 8; 262 pos_y = pos_y % 8;
263 263
264 read_buffer.resize(src_size); 264 read_buffer.resize_destructive(src_size);
265 write_buffer.resize(dst_size); 265 write_buffer.resize_destructive(dst_size);
266 266
267 if (Settings::IsGPULevelExtreme()) { 267 if (Settings::IsGPULevelExtreme()) {
268 memory_manager.ReadBlock(regs.offset_in + offset, read_buffer.data(), src_size); 268 memory_manager.ReadBlock(regs.offset_in + offset, read_buffer.data(), src_size);
@@ -321,10 +321,10 @@ void MaxwellDMA::CopyBlockLinearToBlockLinear() {
321 const u32 pitch = x_elements * bytes_per_pixel; 321 const u32 pitch = x_elements * bytes_per_pixel;
322 const size_t mid_buffer_size = pitch * regs.line_count; 322 const size_t mid_buffer_size = pitch * regs.line_count;
323 323
324 read_buffer.resize(src_size); 324 read_buffer.resize_destructive(src_size);
325 write_buffer.resize(dst_size); 325 write_buffer.resize_destructive(dst_size);
326 326
327 intermediate_buffer.resize(mid_buffer_size); 327 intermediate_buffer.resize_destructive(mid_buffer_size);
328 328
329 memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size); 329 memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size);
330 memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size); 330 memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size);
diff --git a/src/video_core/host1x/vic.cpp b/src/video_core/host1x/vic.cpp
index ac0b7d20e..36a04e4e0 100644
--- a/src/video_core/host1x/vic.cpp
+++ b/src/video_core/host1x/vic.cpp
@@ -155,7 +155,7 @@ void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) {
155 // swizzle pitch linear to block linear 155 // swizzle pitch linear to block linear
156 const u32 block_height = static_cast<u32>(config.block_linear_height_log2); 156 const u32 block_height = static_cast<u32>(config.block_linear_height_log2);
157 const auto size = Texture::CalculateSize(true, 4, width, height, 1, block_height, 0); 157 const auto size = Texture::CalculateSize(true, 4, width, height, 1, block_height, 0);
158 luma_buffer.resize(size); 158 luma_buffer.resize_destructive(size);
159 std::span<const u8> frame_buff(converted_frame_buf_addr, 4 * width * height); 159 std::span<const u8> frame_buff(converted_frame_buf_addr, 4 * width * height);
160 Texture::SwizzleSubrect(luma_buffer, frame_buff, 4, width, height, 1, 0, 0, width, height, 160 Texture::SwizzleSubrect(luma_buffer, frame_buff, 4, width, height, 1, 0, 0, width, height,
161 block_height, 0, width * 4); 161 block_height, 0, width * 4);
@@ -181,8 +181,8 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
181 181
182 const auto stride = static_cast<size_t>(frame->linesize[0]); 182 const auto stride = static_cast<size_t>(frame->linesize[0]);
183 183
184 luma_buffer.resize(aligned_width * surface_height); 184 luma_buffer.resize_destructive(aligned_width * surface_height);
185 chroma_buffer.resize(aligned_width * surface_height / 2); 185 chroma_buffer.resize_destructive(aligned_width * surface_height / 2);
186 186
187 // Populate luma buffer 187 // Populate luma buffer
188 const u8* luma_src = frame->data[0]; 188 const u8* luma_src = frame->data[0];