citra-emu
/
citra
Archived
1
0
Fork 0

gpu: DisplayTransfer: a less amazing algorithm for flip

the old implementation modifies the loop variable in the loop. Though it actually works, it is really confusing. Makes it morereadable now.
This commit is contained in:
wwylele 2016-09-27 21:48:03 +08:00
parent 30ab0fa45d
commit 58ae94af4c
1 changed files with 11 additions and 8 deletions

View File

@ -217,11 +217,14 @@ static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
u32 input_x = x << horizontal_scale; u32 input_x = x << horizontal_scale;
u32 input_y = y << vertical_scale; u32 input_y = y << vertical_scale;
u32 output_y;
if (config.flip_vertically) { if (config.flip_vertically) {
// Flip the y value of the output data, // Flip the y value of the output data,
// we do this after calculating the [x,y] position of the input image // we do this after calculating the [x,y] position of the input image
// to account for the scaling options. // to account for the scaling options.
y = output_height - y - 1; output_y = output_height - y - 1;
} else {
output_y = y;
} }
u32 dst_bytes_per_pixel = GPU::Regs::BytesPerPixel(config.output_format); u32 dst_bytes_per_pixel = GPU::Regs::BytesPerPixel(config.output_format);
@ -232,16 +235,16 @@ static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
if (config.input_linear) { if (config.input_linear) {
if (!config.dont_swizzle) { if (!config.dont_swizzle) {
// Interpret the input as linear and the output as tiled // Interpret the input as linear and the output as tiled
u32 coarse_y = y & ~7; u32 coarse_y = output_y & ~7;
u32 stride = output_width * dst_bytes_per_pixel; u32 stride = output_width * dst_bytes_per_pixel;
src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel; src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel;
dst_offset = dst_offset = VideoCore::GetMortonOffset(x, output_y, dst_bytes_per_pixel) +
VideoCore::GetMortonOffset(x, y, dst_bytes_per_pixel) + coarse_y * stride; coarse_y * stride;
} else { } else {
// Both input and output are linear // Both input and output are linear
src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel; src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel;
dst_offset = (x + y * output_width) * dst_bytes_per_pixel; dst_offset = (x + output_y * output_width) * dst_bytes_per_pixel;
} }
} else { } else {
if (!config.dont_swizzle) { if (!config.dont_swizzle) {
@ -251,10 +254,10 @@ static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
src_offset = VideoCore::GetMortonOffset(input_x, input_y, src_bytes_per_pixel) + src_offset = VideoCore::GetMortonOffset(input_x, input_y, src_bytes_per_pixel) +
coarse_y * stride; coarse_y * stride;
dst_offset = (x + y * output_width) * dst_bytes_per_pixel; dst_offset = (x + output_y * output_width) * dst_bytes_per_pixel;
} else { } else {
// Both input and output are tiled // Both input and output are tiled
u32 out_coarse_y = y & ~7; u32 out_coarse_y = output_y & ~7;
u32 out_stride = output_width * dst_bytes_per_pixel; u32 out_stride = output_width * dst_bytes_per_pixel;
u32 in_coarse_y = input_y & ~7; u32 in_coarse_y = input_y & ~7;
@ -262,7 +265,7 @@ static void DisplayTransfer(const Regs::DisplayTransferConfig& config) {
src_offset = VideoCore::GetMortonOffset(input_x, input_y, src_bytes_per_pixel) + src_offset = VideoCore::GetMortonOffset(input_x, input_y, src_bytes_per_pixel) +
in_coarse_y * in_stride; in_coarse_y * in_stride;
dst_offset = VideoCore::GetMortonOffset(x, y, dst_bytes_per_pixel) + dst_offset = VideoCore::GetMortonOffset(x, output_y, dst_bytes_per_pixel) +
out_coarse_y * out_stride; out_coarse_y * out_stride;
} }
} }