Skip to content

Instantly share code, notes, and snippets.

@Subv
Created February 24, 2015 17:48
Show Gist options
  • Save Subv/7d275572ddfaa9886d92 to your computer and use it in GitHub Desktop.
Save Subv/7d275572ddfaa9886d92 to your computer and use it in GitHub Desktop.
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 643e4ff..4966e61 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -117,11 +117,11 @@ inline void Write(u32 addr, const T data) {
u8* source_pointer = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalInputAddress()));
u8* dest_pointer = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalOutputAddress()));
- // Cheap emulation of horizontal scaling: Just skip each second pixel of the
- // input framebuffer. We keep track of this in the pixel_skip variable.
- unsigned pixel_skip = (config.scale_horizontally != 0) ? 2 : 1;
+ unsigned horizontal_scale = (config.scale_horizontally != 0) ? 2 : 1;
+ unsigned vertical_scale = (config.scale_vertically != 0) ? 2 : 1;
- u32 output_width = config.output_width / pixel_skip;
+ u32 output_width = config.output_width / horizontal_scale;
+ u32 output_height = config.output_height / vertical_scale;
if (config.raw_copy) {
// Raw copies don't perform any kind of conversion whatsoever, just copy the input buffer to the output buffer
@@ -138,7 +138,7 @@ inline void Write(u32 addr, const T data) {
return;
}
- for (u32 y = 0; y < config.output_height; ++y) {
+ for (u32 y = 0; y < output_height; ++y) {
for (u32 x = 0; x < output_width; ++x) {
struct {
int r, g, b, a;
@@ -147,19 +147,30 @@ inline void Write(u32 addr, const T data) {
const unsigned int block_width = 8;
const unsigned int block_height = 8;
- const unsigned int coarse_x = x & ~7;
- const unsigned int coarse_y = y & ~7;
+ unsigned int coarse_x;
- u32 i = MathUtil::MortonInterleave(x, y);
+ if (config.scale_horizontally)
+ coarse_x = (2 * x) & ~7;
+ else
+ coarse_x = x & ~7;
+
+ unsigned int coarse_y;
+
+ if (config.scale_vertically)
+ coarse_y = (2 * y) & ~7;
+ else
+ coarse_y = y & ~7;
+
+ u32 i = MathUtil::MortonInterleave(config.scale_horizontally ? (2 * x) : x, config.scale_vertically ? (2 * y) : y);
const unsigned int offset = coarse_x * block_height;
- u32 dst_offset = (x + y * config.output_width) * GPU::Regs::BytesPerPixel(config.output_format) / pixel_skip;
- u32 src_offset = (offset + i + coarse_y * output_width) * GPU::Regs::BytesPerPixel(config.input_format);
+ u32 dst_offset = (x + y * output_width) * GPU::Regs::BytesPerPixel(config.output_format);
+ u32 src_offset = (offset + i + coarse_y * config.input_width) * GPU::Regs::BytesPerPixel(config.input_format);
if (config.output_tiled) {
// Reverse the addressing, interpret the input as linear and the output as tiled
- src_offset = (x + y * config.output_width) * GPU::Regs::BytesPerPixel(config.input_format) / pixel_skip;
+ src_offset = (x + y * config.input_width) * GPU::Regs::BytesPerPixel(config.input_format);
dst_offset = (offset + i + coarse_y * output_width) * GPU::Regs::BytesPerPixel(config.output_format);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment