diff options
| author | 2024-01-31 22:57:53 +0100 | |
|---|---|---|
| committer | 2024-01-31 23:02:10 +0100 | |
| commit | 5cb9fe7819c2c41f8f1531dca75f01b2d93bf7c5 (patch) | |
| tree | bb701ac918ffb9f833b4a37f5befef050322903c | |
| parent | Merge pull request #12760 from liamwhite/mp-am (diff) | |
| download | yuzu-5cb9fe7819c2c41f8f1531dca75f01b2d93bf7c5.tar.gz yuzu-5cb9fe7819c2c41f8f1531dca75f01b2d93bf7c5.tar.xz yuzu-5cb9fe7819c2c41f8f1531dca75f01b2d93bf7c5.zip | |
SwBlitter: Fix Pitch linear reading/writting
| -rw-r--r-- | src/video_core/engines/sw_blitter/blitter.cpp | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/src/video_core/engines/sw_blitter/blitter.cpp b/src/video_core/engines/sw_blitter/blitter.cpp index 4bc079024..8bcc2f7a7 100644 --- a/src/video_core/engines/sw_blitter/blitter.cpp +++ b/src/video_core/engines/sw_blitter/blitter.cpp | |||
| @@ -111,6 +111,20 @@ void Bilinear(std::span<const f32> input, std::span<f32> output, size_t src_widt | |||
| 111 | } | 111 | } |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | template <bool unpack> | ||
| 115 | void ProcessPitchLinear(std::span<const u8> input, std::span<u8> output, size_t extent_x, | ||
| 116 | size_t extent_y, u32 pitch, u32 x0, u32 y0, size_t bpp) { | ||
| 117 | const size_t base_offset = x0 * bpp; | ||
| 118 | const size_t copy_size = extent_x * bpp; | ||
| 119 | for (size_t y = 0; y < extent_y; y++) { | ||
| 120 | const size_t first_offset = (y + y0) * pitch + base_offset; | ||
| 121 | const size_t second_offset = y * extent_x * bpp; | ||
| 122 | u8* write_to = unpack ? &output[first_offset] : &output[second_offset]; | ||
| 123 | const u8* read_from = unpack ? &input[second_offset] : &input[first_offset]; | ||
| 124 | std::memcpy(write_to, read_from, copy_size); | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 114 | } // namespace | 128 | } // namespace |
| 115 | 129 | ||
| 116 | struct SoftwareBlitEngine::BlitEngineImpl { | 130 | struct SoftwareBlitEngine::BlitEngineImpl { |
| @@ -138,19 +152,6 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, | |||
| 138 | } | 152 | } |
| 139 | return static_cast<size_t>(surface.pitch * surface.height); | 153 | return static_cast<size_t>(surface.pitch * surface.height); |
| 140 | }; | 154 | }; |
| 141 | const auto process_pitch_linear = [](bool unpack, std::span<const u8> input, | ||
| 142 | std::span<u8> output, u32 extent_x, u32 extent_y, | ||
| 143 | u32 pitch, u32 x0, u32 y0, size_t bpp) { | ||
| 144 | const size_t base_offset = x0 * bpp; | ||
| 145 | const size_t copy_size = extent_x * bpp; | ||
| 146 | for (u32 y = y0; y < extent_y; y++) { | ||
| 147 | const size_t first_offset = y * pitch + base_offset; | ||
| 148 | const size_t second_offset = y * extent_x * bpp; | ||
| 149 | u8* write_to = unpack ? &output[first_offset] : &output[second_offset]; | ||
| 150 | const u8* read_from = unpack ? &input[second_offset] : &input[first_offset]; | ||
| 151 | std::memcpy(write_to, read_from, copy_size); | ||
| 152 | } | ||
| 153 | }; | ||
| 154 | 155 | ||
| 155 | const u32 src_extent_x = config.src_x1 - config.src_x0; | 156 | const u32 src_extent_x = config.src_x1 - config.src_x0; |
| 156 | const u32 src_extent_y = config.src_y1 - config.src_y0; | 157 | const u32 src_extent_y = config.src_y1 - config.src_y0; |
| @@ -205,8 +206,8 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, | |||
| 205 | src.depth, config.src_x0, config.src_y0, src_extent_x, src_extent_y, | 206 | src.depth, config.src_x0, config.src_y0, src_extent_x, src_extent_y, |
| 206 | src.block_height, src.block_depth, src_extent_x * src_bytes_per_pixel); | 207 | src.block_height, src.block_depth, src_extent_x * src_bytes_per_pixel); |
| 207 | } else { | 208 | } else { |
| 208 | process_pitch_linear(false, tmp_buffer, impl->src_buffer, src_extent_x, src_extent_y, | 209 | ProcessPitchLinear<false>(tmp_buffer, impl->src_buffer, src_extent_x, src_extent_y, |
| 209 | src.pitch, config.src_x0, config.src_y0, src_bytes_per_pixel); | 210 | src.pitch, config.src_x0, config.src_y0, src_bytes_per_pixel); |
| 210 | } | 211 | } |
| 211 | 212 | ||
| 212 | // Conversion Phase | 213 | // Conversion Phase |
| @@ -229,9 +230,9 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, | |||
| 229 | dst.depth, config.dst_x0, config.dst_y0, dst_extent_x, dst_extent_y, | 230 | dst.depth, config.dst_x0, config.dst_y0, dst_extent_x, dst_extent_y, |
| 230 | dst.block_height, dst.block_depth, dst_extent_x * dst_bytes_per_pixel); | 231 | dst.block_height, dst.block_depth, dst_extent_x * dst_bytes_per_pixel); |
| 231 | } else { | 232 | } else { |
| 232 | process_pitch_linear(true, impl->dst_buffer, tmp_buffer2, dst_extent_x, dst_extent_y, | 233 | ProcessPitchLinear<true>(impl->dst_buffer, tmp_buffer2, dst_extent_x, dst_extent_y, |
| 233 | dst.pitch, config.dst_x0, config.dst_y0, | 234 | dst.pitch, config.dst_x0, config.dst_y0, |
| 234 | static_cast<size_t>(dst_bytes_per_pixel)); | 235 | static_cast<size_t>(dst_bytes_per_pixel)); |
| 235 | } | 236 | } |
| 236 | return true; | 237 | return true; |
| 237 | } | 238 | } |