diff options
| author | 2022-12-19 22:40:50 -0500 | |
|---|---|---|
| committer | 2022-12-19 22:40:50 -0500 | |
| commit | c6590ad07b384762fd90ee8852796ec681a69286 (patch) | |
| tree | c0d8d2d157f3bb4be01331f2da459c0f68ca4d7b /src | |
| parent | tests: Add ScratchBuffer tests (diff) | |
| download | yuzu-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.h | 17 | ||||
| -rw-r--r-- | src/tests/common/scratch_buffer.cpp | 78 | ||||
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 2 | ||||
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/engines/engine_upload.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_dma.cpp | 18 | ||||
| -rw-r--r-- | src/video_core/host1x/vic.cpp | 6 |
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 | ||
| 32 | TEST_CASE("ScratchBuffer: Resize Grow", "[common]") { | 32 | TEST_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 | ||
| 48 | TEST_CASE("ScratchBuffer: Resize Shrink", "[common]") { | 48 | TEST_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 | |||
| 72 | TEST_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 | |||
| 96 | TEST_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 | |||
| 120 | TEST_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 | ||
| 1927 | template <class P> | 1927 | template <class P> |
| 1928 | std::span<u8> BufferCache<P>::ImmediateBuffer(size_t wanted_capacity) { | 1928 | std::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_) { | |||
| 24 | void State::ProcessExec(const bool is_linear_) { | 24 | void 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]; |