diff options
Diffstat (limited to 'src/core/hw/gpu.cpp')
| -rw-r--r-- | src/core/hw/gpu.cpp | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index 49fc574bc..31989f445 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp | |||
| @@ -290,13 +290,54 @@ inline void Write(u32 addr, const T data) { | |||
| 290 | u8* source_pointer = Memory::GetPointer(g_regs.display_transfer.GetPhysicalInputAddress()); | 290 | u8* source_pointer = Memory::GetPointer(g_regs.display_transfer.GetPhysicalInputAddress()); |
| 291 | u8* dest_pointer = Memory::GetPointer(g_regs.display_transfer.GetPhysicalOutputAddress()); | 291 | u8* dest_pointer = Memory::GetPointer(g_regs.display_transfer.GetPhysicalOutputAddress()); |
| 292 | 292 | ||
| 293 | |||
| 294 | // TODO: Perform display transfer correctly! | ||
| 295 | for (int y = 0; y < g_regs.display_transfer.output_height; ++y) { | 293 | for (int y = 0; y < g_regs.display_transfer.output_height; ++y) { |
| 296 | // TODO: Copy size is just guesswork! | 294 | // TODO: Why does the register seem to hold twice the framebuffer width? |
| 297 | memcpy(dest_pointer + y * g_regs.display_transfer.output_width * 4, | 295 | for (int x = 0; x < g_regs.display_transfer.output_width / 2; ++x) { |
| 298 | source_pointer + y * g_regs.display_transfer.input_width * 4, | 296 | int source[4] = { 0, 0, 0, 0}; // rgba; |
| 299 | g_regs.display_transfer.output_width * 4); | 297 | |
| 298 | switch (g_regs.display_transfer.input_format) { | ||
| 299 | case Registers::FramebufferFormat::RGBA8: | ||
| 300 | { | ||
| 301 | // TODO: Most likely got the component order messed up. | ||
| 302 | u8* srcptr = source_pointer + x * 4 + y * g_regs.display_transfer.input_width * 4 / 2; | ||
| 303 | source[0] = srcptr[0]; // blue | ||
| 304 | source[1] = srcptr[1]; // green | ||
| 305 | source[2] = srcptr[2]; // red | ||
| 306 | source[3] = srcptr[3]; // alpha | ||
| 307 | break; | ||
| 308 | } | ||
| 309 | |||
| 310 | default: | ||
| 311 | ERROR_LOG(GPU, "Unknown source framebuffer format %x", (int)g_regs.display_transfer.input_format.Value()); | ||
| 312 | break; | ||
| 313 | } | ||
| 314 | |||
| 315 | switch (g_regs.display_transfer.output_format) { | ||
| 316 | /*case Registers::FramebufferFormat::RGBA8: | ||
| 317 | { | ||
| 318 | // TODO: Untested | ||
| 319 | u8* dstptr = (u32*)(dest_pointer + x * 4 + y * g_regs.display_transfer.output_width * 4); | ||
| 320 | dstptr[0] = source[0]; | ||
| 321 | dstptr[1] = source[1]; | ||
| 322 | dstptr[2] = source[2]; | ||
| 323 | dstptr[3] = source[3]; | ||
| 324 | break; | ||
| 325 | }*/ | ||
| 326 | |||
| 327 | case Registers::FramebufferFormat::RGB8: | ||
| 328 | { | ||
| 329 | u8* dstptr = dest_pointer + x * 3 + y * g_regs.display_transfer.output_width * 3 / 2; | ||
| 330 | dstptr[0] = source[0]; // blue | ||
| 331 | dstptr[1] = source[1]; // green | ||
| 332 | dstptr[2] = source[2]; // red | ||
| 333 | break; | ||
| 334 | } | ||
| 335 | |||
| 336 | default: | ||
| 337 | ERROR_LOG(GPU, "Unknown destination framebuffer format %x", static_cast<int>(g_regs.display_transfer.output_format.Value())); | ||
| 338 | break; | ||
| 339 | } | ||
| 340 | } | ||
| 300 | } | 341 | } |
| 301 | 342 | ||
| 302 | DEBUG_LOG(GPU, "DisplayTriggerTransfer: %x bytes from %x(%xx%x)-> %x(%xx%x), dst format %x", | 343 | DEBUG_LOG(GPU, "DisplayTriggerTransfer: %x bytes from %x(%xx%x)-> %x(%xx%x), dst format %x", |