diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index d54b57869b..d9d30b9a18 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -691,15 +691,6 @@ namespace rsx const u32 in_bpp = (src_color_format == rsx::blit_engine::transfer_source_format::r5g6b5) ? 2 : 4; // bytes per pixel const u32 out_bpp = (dst_color_format == rsx::blit_engine::transfer_destination_format::r5g6b5) ? 2 : 4; - const u32 in_offset = u32(in_x * in_bpp + in_pitch * in_y); - const s32 out_offset = out_x * out_bpp + out_pitch * out_y; - - const tiled_region src_region = rsx->get_tiled_address(src_offset + in_offset, src_dma & 0xf); - const tiled_region dst_region = rsx->get_tiled_address(dst_offset + out_offset, dst_dma & 0xf); - - u8* pixels_src = src_region.tile ? src_region.ptr + src_region.base : src_region.ptr; - u8* pixels_dst = vm::_ptr(get_address(dst_offset + out_offset, dst_dma)); - if (out_pitch == 0) { out_pitch = out_bpp * out_w; @@ -710,6 +701,15 @@ namespace rsx in_pitch = in_bpp * in_w; } + const u32 in_offset = u32(in_x * in_bpp + in_pitch * in_y); + const s32 out_offset = out_x * out_bpp + out_pitch * out_y; + + const tiled_region src_region = rsx->get_tiled_address(src_offset + in_offset, src_dma & 0xf); + const tiled_region dst_region = rsx->get_tiled_address(dst_offset + out_offset, dst_dma & 0xf); + + u8* pixels_src = src_region.tile ? src_region.ptr + src_region.base : src_region.ptr; + u8* pixels_dst = vm::_ptr(get_address(dst_offset + out_offset, dst_dma)); + const auto read_address = get_address(src_offset, src_dma); rsx->read_barrier(read_address, in_pitch * in_h); @@ -940,13 +940,13 @@ namespace rsx switch (out_bpp) { case 1: - convert_linear_swizzle(linear_pixels, swizzled_pixels, sw_width, sw_height, false); + convert_linear_swizzle(linear_pixels, swizzled_pixels, sw_width, sw_height, in_pitch, false); break; case 2: - convert_linear_swizzle(linear_pixels, swizzled_pixels, sw_width, sw_height, false); + convert_linear_swizzle(linear_pixels, swizzled_pixels, sw_width, sw_height, in_pitch, false); break; case 4: - convert_linear_swizzle(linear_pixels, swizzled_pixels, sw_width, sw_height, false); + convert_linear_swizzle(linear_pixels, swizzled_pixels, sw_width, sw_height, in_pitch, false); break; } diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index b6d43363a8..7ddbf279e3 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -338,7 +338,7 @@ namespace rsx * Restriction: Only works with 2D surfaces */ template - void convert_linear_swizzle(void* input_pixels, void* output_pixels, u16 width, u16 height, bool input_is_swizzled) + void convert_linear_swizzle(void* input_pixels, void* output_pixels, u16 width, u16 height, u32 pitch, bool input_is_swizzled) { u32 log2width = ceil_log2(width); u32 log2height = ceil_log2(height); @@ -362,11 +362,13 @@ namespace rsx u32 offs_x0 = 0; //total y-carry offset for x u32 y_incr = limit_mask; + u32 adv = pitch / sizeof(T); + if (!input_is_swizzled) { for (int y = 0; y < height; ++y) { - T *src = static_cast(input_pixels) + y * width; + T* src = static_cast(input_pixels) + y * adv; T *dst = static_cast(output_pixels) + offs_y; offs_x = offs_x0; @@ -389,7 +391,7 @@ namespace rsx for (int y = 0; y < height; ++y) { T *src = static_cast(input_pixels) + offs_y; - T *dst = static_cast(output_pixels) + y * width; + T* dst = static_cast(output_pixels) + y * adv; offs_x = offs_x0; for (int x = 0; x < width; ++x) @@ -419,7 +421,7 @@ namespace rsx { if (depth == 1) { - convert_linear_swizzle(input_pixels, output_pixels, width, height, true); + convert_linear_swizzle(input_pixels, output_pixels, width, height, width * sizeof(T), true); return; }