summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hw/gpu.cpp21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 256e11c37..58eec3005 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -100,22 +100,25 @@ inline void Write(u32 addr, const T data) {
100 u8* source_pointer = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalInputAddress())); 100 u8* source_pointer = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalInputAddress()));
101 u8* dest_pointer = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalOutputAddress())); 101 u8* dest_pointer = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalOutputAddress()));
102 102
103 // Cheap emulation of horizontal scaling: Just skip each second pixel of the
104 // input framebuffer. We keep track of this in the pixel_skip variable.
105 unsigned pixel_skip = (config.scale_horizontally != 0) ? 2 : 1;
106
107 u32 output_width = config.output_width / pixel_skip;
108
103 for (u32 y = 0; y < config.output_height; ++y) { 109 for (u32 y = 0; y < config.output_height; ++y) {
104 // TODO: Why does the register seem to hold twice the framebuffer width? 110 // TODO: Why does the register seem to hold twice the framebuffer width?
105 for (u32 x = 0; x < config.output_width; ++x) { 111
112 for (u32 x = 0; x < output_width; ++x) {
106 struct { 113 struct {
107 int r, g, b, a; 114 int r, g, b, a;
108 } source_color = { 0, 0, 0, 0 }; 115 } source_color = { 0, 0, 0, 0 };
109 116
110 // Cheap emulation of horizontal scaling: Just skip each second pixel of the
111 // input framebuffer. We keep track of this in the pixel_skip variable.
112 unsigned pixel_skip = (config.scale_horizontally != 0) ? 2 : 1;
113
114 switch (config.input_format) { 117 switch (config.input_format) {
115 case Regs::PixelFormat::RGBA8: 118 case Regs::PixelFormat::RGBA8:
116 { 119 {
117 // TODO: Most likely got the component order messed up. 120 // TODO: Most likely got the component order messed up.
118 u8* srcptr = source_pointer + x * 4 * pixel_skip + y * config.input_width * 4 * pixel_skip; 121 u8* srcptr = source_pointer + (x * pixel_skip + y * config.input_width) * 4;
119 source_color.r = srcptr[0]; // blue 122 source_color.r = srcptr[0]; // blue
120 source_color.g = srcptr[1]; // green 123 source_color.g = srcptr[1]; // green
121 source_color.b = srcptr[2]; // red 124 source_color.b = srcptr[2]; // red
@@ -143,7 +146,7 @@ inline void Write(u32 addr, const T data) {
143 case Regs::PixelFormat::RGB8: 146 case Regs::PixelFormat::RGB8:
144 { 147 {
145 // TODO: Most likely got the component order messed up. 148 // TODO: Most likely got the component order messed up.
146 u8* dstptr = dest_pointer + x * 3 + y * config.output_width * 3; 149 u8* dstptr = dest_pointer + (x + y * output_width) * 3;
147 dstptr[0] = source_color.r; // blue 150 dstptr[0] = source_color.r; // blue
148 dstptr[1] = source_color.g; // green 151 dstptr[1] = source_color.g; // green
149 dstptr[2] = source_color.b; // red 152 dstptr[2] = source_color.b; // red
@@ -158,9 +161,9 @@ inline void Write(u32 addr, const T data) {
158 } 161 }
159 162
160 LOG_TRACE(HW_GPU, "DisplayTriggerTransfer: 0x%08x bytes from 0x%08x(%ux%u)-> 0x%08x(%ux%u), dst format %x", 163 LOG_TRACE(HW_GPU, "DisplayTriggerTransfer: 0x%08x bytes from 0x%08x(%ux%u)-> 0x%08x(%ux%u), dst format %x",
161 config.output_height * config.output_width * 4, 164 config.output_height * output_width * 4,
162 config.GetPhysicalInputAddress(), (u32)config.input_width, (u32)config.input_height, 165 config.GetPhysicalInputAddress(), (u32)config.input_width, (u32)config.input_height,
163 config.GetPhysicalOutputAddress(), (u32)config.output_width, (u32)config.output_height, 166 config.GetPhysicalOutputAddress(), (u32)output_width, (u32)config.output_height,
164 config.output_format.Value()); 167 config.output_format.Value());
165 168
166 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); 169 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF);