From 63dbff9b1f2cd6f330c8b4aee8e35d1c61cec87e Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 19 Jul 2015 21:30:42 -0500 Subject: GPU/DisplayTransfer: Implemented bit 5 in the transfer flags. It tells the GPU to not swizzle/de-swizzle the input during the transfer. --- src/core/hw/gpu.cpp | 42 ++++++++++++++++++++++++++++++------------ src/core/hw/gpu.h | 1 + 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index a3a7d128..2a338e8f 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp @@ -217,19 +217,37 @@ inline void Write(u32 addr, const T data) { u32 dst_offset; if (config.output_tiled) { - // Interpret the input as linear and the output as tiled - u32 coarse_y = y & ~7; - u32 stride = output_width * dst_bytes_per_pixel; - - src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel; - dst_offset = VideoCore::GetMortonOffset(x, y, dst_bytes_per_pixel) + coarse_y * stride; + if (!config.dont_swizzle) { + // Interpret the input as linear and the output as tiled + u32 coarse_y = y & ~7; + u32 stride = output_width * dst_bytes_per_pixel; + + src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel; + dst_offset = VideoCore::GetMortonOffset(x, y, dst_bytes_per_pixel) + coarse_y * stride; + } else { + // Both input and output are linear + src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel; + dst_offset = (x + y * output_width) * dst_bytes_per_pixel; + } } else { - // Interpret the input as tiled and the output as linear - u32 coarse_y = input_y & ~7; - u32 stride = config.input_width * src_bytes_per_pixel; - - src_offset = VideoCore::GetMortonOffset(input_x, input_y, src_bytes_per_pixel) + coarse_y * stride; - dst_offset = (x + y * output_width) * dst_bytes_per_pixel; + if (!config.dont_swizzle) { + // Interpret the input as tiled and the output as linear + u32 coarse_y = input_y & ~7; + u32 stride = config.input_width * src_bytes_per_pixel; + + src_offset = VideoCore::GetMortonOffset(input_x, input_y, src_bytes_per_pixel) + coarse_y * stride; + dst_offset = (x + y * output_width) * dst_bytes_per_pixel; + } else { + // Both input and output are tiled + u32 out_coarse_y = y & ~7; + u32 out_stride = output_width * dst_bytes_per_pixel; + + u32 in_coarse_y = input_y & ~7; + u32 in_stride = config.input_width * src_bytes_per_pixel; + + src_offset = VideoCore::GetMortonOffset(input_x, input_y, src_bytes_per_pixel) + in_coarse_y * in_stride; + dst_offset = VideoCore::GetMortonOffset(x, y, dst_bytes_per_pixel) + out_coarse_y * out_stride; + } } const u8* src_pixel = src_pointer + src_offset; diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index 5b8c43f8..daad506f 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -203,6 +203,7 @@ struct Regs { BitField< 0, 1, u32> flip_vertically; // flips input data vertically BitField< 1, 1, u32> output_tiled; // Converts from linear to tiled format BitField< 3, 1, u32> raw_copy; // Copies the data without performing any processing + BitField< 5, 1, u32> dont_swizzle; BitField< 8, 3, PixelFormat> input_format; BitField<12, 3, PixelFormat> output_format; -- cgit v1.2.3