summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2024-01-31 22:57:53 +0100
committerGravatar Fernando Sahmkow2024-01-31 23:02:10 +0100
commit5cb9fe7819c2c41f8f1531dca75f01b2d93bf7c5 (patch)
treebb701ac918ffb9f833b4a37f5befef050322903c
parentMerge pull request #12760 from liamwhite/mp-am (diff)
downloadyuzu-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.cpp37
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
114template <bool unpack>
115void 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
116struct SoftwareBlitEngine::BlitEngineImpl { 130struct 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}