Răsfoiți Sursa

Pica/GPU: Change hardware registers to use physical addresses rather than virtual ones.

This cleans up the mess that address reading/writing had become and makes the code a *lot* more sensible.
This adds a physical<->virtual address converter to mem_map.h. For further accuracy, we will want to properly extend this to support a wider range of address regions. For now, this makes simply homebrew applications work in a good manner though.
Tony Wasserka 12 ani în urmă
părinte
comite
7b6a7d7dfb

+ 9 - 9
src/core/hle/service/gsp.cpp

@@ -173,7 +173,7 @@ void ExecuteCommand(const Command& command) {
     case CommandId::SET_COMMAND_LIST_LAST:
     {
         auto& params = command.set_command_list_last;
-        WriteGPURegister(GPU_REG_INDEX(command_processor_config.address), params.address >> 3);
+        WriteGPURegister(GPU_REG_INDEX(command_processor_config.address), Memory::VirtualToPhysicalAddress(params.address) >> 3);
         WriteGPURegister(GPU_REG_INDEX(command_processor_config.size), params.size >> 3);
 
         // TODO: Not sure if we are supposed to always write this .. seems to trigger processing though
@@ -193,13 +193,13 @@ void ExecuteCommand(const Command& command) {
     case CommandId::SET_MEMORY_FILL:
     {
         auto& params = command.memory_fill;
-        WriteGPURegister(GPU_REG_INDEX(memory_fill_config[0].address_start), params.start1 >> 3);
-        WriteGPURegister(GPU_REG_INDEX(memory_fill_config[0].address_end), params.end1 >> 3);
+        WriteGPURegister(GPU_REG_INDEX(memory_fill_config[0].address_start), Memory::VirtualToPhysicalAddress(params.start1) >> 3);
+        WriteGPURegister(GPU_REG_INDEX(memory_fill_config[0].address_end), Memory::VirtualToPhysicalAddress(params.end1) >> 3);
         WriteGPURegister(GPU_REG_INDEX(memory_fill_config[0].size), params.end1 - params.start1);
         WriteGPURegister(GPU_REG_INDEX(memory_fill_config[0].value), params.value1);
 
-        WriteGPURegister(GPU_REG_INDEX(memory_fill_config[1].address_start), params.start2 >> 3);
-        WriteGPURegister(GPU_REG_INDEX(memory_fill_config[1].address_end), params.end2 >> 3);
+        WriteGPURegister(GPU_REG_INDEX(memory_fill_config[1].address_start), Memory::VirtualToPhysicalAddress(params.start2) >> 3);
+        WriteGPURegister(GPU_REG_INDEX(memory_fill_config[1].address_end), Memory::VirtualToPhysicalAddress(params.end2) >> 3);
         WriteGPURegister(GPU_REG_INDEX(memory_fill_config[1].size), params.end2 - params.start2);
         WriteGPURegister(GPU_REG_INDEX(memory_fill_config[1].value), params.value2);
         break;
@@ -208,8 +208,8 @@ void ExecuteCommand(const Command& command) {
     case CommandId::SET_DISPLAY_TRANSFER:
     {
         auto& params = command.image_copy;
-        WriteGPURegister(GPU_REG_INDEX(display_transfer_config.input_address), params.in_buffer_address >> 3);
-        WriteGPURegister(GPU_REG_INDEX(display_transfer_config.output_address), params.out_buffer_address >> 3);
+        WriteGPURegister(GPU_REG_INDEX(display_transfer_config.input_address), Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3);
+        WriteGPURegister(GPU_REG_INDEX(display_transfer_config.output_address), Memory::VirtualToPhysicalAddress(params.out_buffer_address) >> 3);
         WriteGPURegister(GPU_REG_INDEX(display_transfer_config.input_size), params.in_buffer_size);
         WriteGPURegister(GPU_REG_INDEX(display_transfer_config.output_size), params.out_buffer_size);
         WriteGPURegister(GPU_REG_INDEX(display_transfer_config.flags), params.flags);
@@ -230,8 +230,8 @@ void ExecuteCommand(const Command& command) {
     case CommandId::SET_TEXTURE_COPY:
     {
         auto& params = command.image_copy;
-        WriteGPURegister(GPU_REG_INDEX(display_transfer_config.input_address), params.in_buffer_address >> 3);
-        WriteGPURegister(GPU_REG_INDEX(display_transfer_config.output_address), params.out_buffer_address >> 3);
+        WriteGPURegister(GPU_REG_INDEX(display_transfer_config.input_address), Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3);
+        WriteGPURegister(GPU_REG_INDEX(display_transfer_config.output_address), Memory::VirtualToPhysicalAddress(params.out_buffer_address) >> 3);
         WriteGPURegister(GPU_REG_INDEX(display_transfer_config.input_size), params.in_buffer_size);
         WriteGPURegister(GPU_REG_INDEX(display_transfer_config.output_size), params.out_buffer_size);
         WriteGPURegister(GPU_REG_INDEX(display_transfer_config.flags), params.flags);

+ 18 - 84
src/core/hw/gpu.cpp

@@ -24,83 +24,6 @@ Regs g_regs;
 u32 g_cur_line = 0;         ///< Current vertical screen line
 u64 g_last_line_ticks = 0;  ///< CPU tick count from last vertical screen line
 
-/**
- * Sets whether the framebuffers are in the GSP heap (FCRAM) or VRAM
- * @param
- */
-void SetFramebufferLocation(const FramebufferLocation mode) {
-    switch (mode) {
-    case FRAMEBUFFER_LOCATION_FCRAM:
-    {
-        auto& framebuffer_top = g_regs.framebuffer_config[0];
-        auto& framebuffer_sub = g_regs.framebuffer_config[1];
-
-        framebuffer_top.address_left1  = PADDR_TOP_LEFT_FRAME1;
-        framebuffer_top.address_left2  = PADDR_TOP_LEFT_FRAME2;
-        framebuffer_top.address_right1 = PADDR_TOP_RIGHT_FRAME1;
-        framebuffer_top.address_right2 = PADDR_TOP_RIGHT_FRAME2;
-        framebuffer_sub.address_left1  = PADDR_SUB_FRAME1;
-        //framebuffer_sub.address_left2  = unknown;
-        framebuffer_sub.address_right1 = PADDR_SUB_FRAME2;
-        //framebuffer_sub.address_right2 = unknown;
-        break;
-    }
-
-    case FRAMEBUFFER_LOCATION_VRAM:
-    {
-        auto& framebuffer_top = g_regs.framebuffer_config[0];
-        auto& framebuffer_sub = g_regs.framebuffer_config[1];
-
-        framebuffer_top.address_left1  = PADDR_VRAM_TOP_LEFT_FRAME1;
-        framebuffer_top.address_left2  = PADDR_VRAM_TOP_LEFT_FRAME2;
-        framebuffer_top.address_right1 = PADDR_VRAM_TOP_RIGHT_FRAME1;
-        framebuffer_top.address_right2 = PADDR_VRAM_TOP_RIGHT_FRAME2;
-        framebuffer_sub.address_left1  = PADDR_VRAM_SUB_FRAME1;
-        //framebuffer_sub.address_left2  = unknown;
-        framebuffer_sub.address_right1 = PADDR_VRAM_SUB_FRAME2;
-        //framebuffer_sub.address_right2 = unknown;
-        break;
-    }
-    }
-}
-
-/**
- * Gets the location of the framebuffers
- * @return Location of framebuffers as FramebufferLocation enum
- */
-FramebufferLocation GetFramebufferLocation(u32 address) {
-    if ((address & ~Memory::VRAM_MASK) == Memory::VRAM_PADDR) {
-        return FRAMEBUFFER_LOCATION_VRAM;
-    } else if ((address & ~Memory::FCRAM_MASK) == Memory::FCRAM_PADDR) {
-        return FRAMEBUFFER_LOCATION_FCRAM;
-    } else {
-        ERROR_LOG(GPU, "unknown framebuffer location!");
-    }
-    return FRAMEBUFFER_LOCATION_UNKNOWN;
-}
-
-u32 GetFramebufferAddr(const u32 address) {
-    switch (GetFramebufferLocation(address)) {
-    case FRAMEBUFFER_LOCATION_FCRAM:
-        return Memory::VirtualAddressFromPhysical_FCRAM(address);
-    case FRAMEBUFFER_LOCATION_VRAM:
-        return Memory::VirtualAddressFromPhysical_VRAM(address);
-    default:
-        ERROR_LOG(GPU, "unknown framebuffer location");
-    }
-    return 0;
-}
-
-/**
- * Gets a read-only pointer to a framebuffer in memory
- * @param address Physical address of framebuffer
- * @return Returns const pointer to raw framebuffer
- */
-const u8* GetFramebufferPointer(const u32 address) {
-    u32 addr = GetFramebufferAddr(address);
-    return (addr != 0) ? Memory::GetPointer(addr) : nullptr;
-}
-
 template <typename T>
 inline void Read(T &var, const u32 raw_addr) {
     u32 addr = raw_addr - 0x1EF00000;
@@ -141,8 +64,8 @@ inline void Write(u32 addr, const T data) {
         // TODO: Not sure if this check should be done at GSP level instead
         if (config.address_start) {
             // TODO: Not sure if this algorithm is correct, particularly because it doesn't use the size member at all
-            u32* start = (u32*)Memory::GetPointer(config.GetStartAddress());
-            u32* end = (u32*)Memory::GetPointer(config.GetEndAddress());
+            u32* start = (u32*)Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetStartAddress()));
+            u32* end = (u32*)Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetEndAddress()));
             for (u32* ptr = start; ptr < end; ++ptr)
                 *ptr = bswap32(config.value); // TODO: This is just a workaround to missing framebuffer format emulation
 
@@ -155,8 +78,8 @@ inline void Write(u32 addr, const T data) {
     {
         const auto& config = g_regs.display_transfer_config;
         if (config.trigger & 1) {
-            u8* source_pointer = Memory::GetPointer(config.GetPhysicalInputAddress());
-            u8* dest_pointer = Memory::GetPointer(config.GetPhysicalOutputAddress());
+            u8* source_pointer = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalInputAddress()));
+            u8* dest_pointer = Memory::GetPointer(Memory::PhysicalToVirtualAddress(config.GetPhysicalOutputAddress()));
 
             for (int y = 0; y < config.output_height; ++y) {
                 // TODO: Why does the register seem to hold twice the framebuffer width?
@@ -276,11 +199,22 @@ void Init() {
     g_cur_line = 0;
     g_last_line_ticks = Core::g_app_core->GetTicks();
 
-//    SetFramebufferLocation(FRAMEBUFFER_LOCATION_FCRAM);
-    SetFramebufferLocation(FRAMEBUFFER_LOCATION_VRAM);
-
     auto& framebuffer_top = g_regs.framebuffer_config[0];
     auto& framebuffer_sub = g_regs.framebuffer_config[1];
+
+    // Setup default framebuffer addresses (located in VRAM)
+    // .. or at least these are the ones used by system applets.
+    // There's probably a smarter way to come up with addresses
+    // like this which does not require hardcoding.
+    framebuffer_top.address_left1  = 0x181E6000;
+    framebuffer_top.address_left2  = 0x1822C800;
+    framebuffer_top.address_right1 = 0x18273000;
+    framebuffer_top.address_right2 = 0x182B9800;
+    framebuffer_sub.address_left1  = 0x1848F000;
+    //framebuffer_sub.address_left2  = unknown;
+    framebuffer_sub.address_right1 = 0x184C7800;
+    //framebuffer_sub.address_right2 = unknown;
+
     // TODO: Width should be 240 instead?
     framebuffer_top.width = 480;
     framebuffer_top.height = 400;

+ 0 - 66
src/core/hw/gpu.h

@@ -249,72 +249,6 @@ static_assert(sizeof(Regs) == 0x1000 * sizeof(u32), "Invalid total size of regis
 
 extern Regs g_regs;
 
-enum {
-    TOP_ASPECT_X        = 0x5,
-    TOP_ASPECT_Y        = 0x3,
-
-    TOP_HEIGHT          = 240,
-    TOP_WIDTH           = 400,
-    BOTTOM_WIDTH        = 320,
-
-    // Physical addresses in FCRAM (chosen arbitrarily)
-    PADDR_TOP_LEFT_FRAME1       = 0x201D4C00,
-    PADDR_TOP_LEFT_FRAME2       = 0x202D4C00,
-    PADDR_TOP_RIGHT_FRAME1      = 0x203D4C00,
-    PADDR_TOP_RIGHT_FRAME2      = 0x204D4C00,
-    PADDR_SUB_FRAME1            = 0x205D4C00,
-    PADDR_SUB_FRAME2            = 0x206D4C00,
-    // Physical addresses in FCRAM used by ARM9 applications
-/*    PADDR_TOP_LEFT_FRAME1       = 0x20184E60,
-    PADDR_TOP_LEFT_FRAME2       = 0x201CB370,
-    PADDR_TOP_RIGHT_FRAME1      = 0x20282160,
-    PADDR_TOP_RIGHT_FRAME2      = 0x202C8670,
-    PADDR_SUB_FRAME1            = 0x202118E0,
-    PADDR_SUB_FRAME2            = 0x20249CF0,*/
-
-    // Physical addresses in VRAM
-    // TODO: These should just be deduced from the ones above
-    PADDR_VRAM_TOP_LEFT_FRAME1  = 0x181D4C00,
-    PADDR_VRAM_TOP_LEFT_FRAME2  = 0x182D4C00,
-    PADDR_VRAM_TOP_RIGHT_FRAME1 = 0x183D4C00,
-    PADDR_VRAM_TOP_RIGHT_FRAME2 = 0x184D4C00,
-    PADDR_VRAM_SUB_FRAME1       = 0x185D4C00,
-    PADDR_VRAM_SUB_FRAME2       = 0x186D4C00,
-    // Physical addresses in VRAM used by ARM9 applications
-/*    PADDR_VRAM_TOP_LEFT_FRAME2  = 0x181CB370,
-    PADDR_VRAM_TOP_RIGHT_FRAME1 = 0x18282160,
-    PADDR_VRAM_TOP_RIGHT_FRAME2 = 0x182C8670,
-    PADDR_VRAM_SUB_FRAME1       = 0x182118E0,
-    PADDR_VRAM_SUB_FRAME2       = 0x18249CF0,*/
-};
-
-/// Framebuffer location
-enum FramebufferLocation {
-    FRAMEBUFFER_LOCATION_UNKNOWN,   ///< Framebuffer location is unknown
-    FRAMEBUFFER_LOCATION_FCRAM,     ///< Framebuffer is in the GSP heap
-    FRAMEBUFFER_LOCATION_VRAM,      ///< Framebuffer is in VRAM
-};
-
-/**
- * Sets whether the framebuffers are in the GSP heap (FCRAM) or VRAM
- * @param
- */
-void SetFramebufferLocation(const FramebufferLocation mode);
-
-/**
- * Gets a read-only pointer to a framebuffer in memory
- * @param address Physical address of framebuffer
- * @return Returns const pointer to raw framebuffer
- */
-const u8* GetFramebufferPointer(const u32 address);
-
-u32 GetFramebufferAddr(const u32 address);
-
-/**
- * Gets the location of the framebuffers
- */
-FramebufferLocation GetFramebufferLocation(u32 address);
-
 template <typename T>
 void Read(T &var, const u32 addr);
 

+ 2 - 2
src/core/mem_map.cpp

@@ -72,14 +72,14 @@ void Init() {
 
     g_base = MemoryMap_Setup(g_views, kNumMemViews, flags, &g_arena);
 
-    NOTICE_LOG(MEMMAP, "initialized OK, RAM at %p (mirror at 0 @ %p)", g_heap, 
+    NOTICE_LOG(MEMMAP, "initialized OK, RAM at %p (mirror at 0 @ %p)", g_heap,
         g_physical_fcram);
 }
 
 void Shutdown() {
     u32 flags = 0;
     MemoryMap_Shutdown(g_views, kNumMemViews, flags, &g_arena);
-    
+
     g_arena.ReleaseSpace();
     g_base = NULL;
 

+ 7 - 15
src/core/mem_map.h

@@ -14,7 +14,6 @@ namespace Memory {
 enum {
     BOOTROM_SIZE            = 0x00010000,   ///< Bootrom (super secret code/data @ 0x8000) size
     MPCORE_PRIV_SIZE        = 0x00002000,   ///< MPCore private memory region size
-    VRAM_SIZE               = 0x00600000,   ///< VRAM size
     DSP_SIZE                = 0x00080000,   ///< DSP memory size
     AXI_WRAM_SIZE           = 0x00080000,   ///< AXI WRAM size
 
@@ -23,8 +22,6 @@ enum {
     FCRAM_PADDR_END         = (FCRAM_PADDR + FCRAM_SIZE),       ///< FCRAM end of physical space
     FCRAM_VADDR             = 0x08000000,                       ///< FCRAM virtual address
     FCRAM_VADDR_END         = (FCRAM_VADDR + FCRAM_SIZE),       ///< FCRAM end of virtual space
-    FCRAM_VADDR_FW0B        = 0xF0000000,                       ///< FCRAM adress for firmare FW0B
-    FCRAM_VADDR_FW0B_END    = (FCRAM_VADDR_FW0B + FCRAM_SIZE),  ///< FCRAM adress end for FW0B
     FCRAM_MASK              = (FCRAM_SIZE - 1),                 ///< FCRAM mask
 
     SHARED_MEMORY_SIZE      = 0x04000000,   ///< Shared memory size
@@ -73,6 +70,7 @@ enum {
     HARDWARE_IO_PADDR_END   = (HARDWARE_IO_PADDR + HARDWARE_IO_SIZE),
     HARDWARE_IO_VADDR_END   = (HARDWARE_IO_VADDR + HARDWARE_IO_SIZE),
 
+    VRAM_SIZE               = 0x00600000,
     VRAM_PADDR              = 0x18000000,
     VRAM_VADDR              = 0x1F000000,
     VRAM_PADDR_END          = (VRAM_PADDR + VRAM_SIZE),
@@ -112,7 +110,7 @@ struct MemoryBlock {
 
 // In 64-bit, this might point to "high memory" (above the 32-bit limit),
 // so be sure to load it into a 64-bit register.
-extern u8 *g_base; 
+extern u8 *g_base;
 
 // These are guaranteed to point to "low memory" addresses (sub-32-bit).
 // 64-bit: Pointers to low-mem (sub-0x10000000) mirror
@@ -147,7 +145,7 @@ void Write32(const u32 addr, const u32 data);
 
 void WriteBlock(const u32 addr, const u8* data, const int size);
 
-u8* GetPointer(const u32 Address);
+u8* GetPointer(const u32 virtual_address);
 
 /**
  * Maps a block of memory on the heap
@@ -169,16 +167,10 @@ inline const char* GetCharPointer(const u32 address) {
     return (const char *)GetPointer(address);
 }
 
-inline const u32 VirtualAddressFromPhysical_FCRAM(const u32 address) {
-    return ((address & FCRAM_MASK) | FCRAM_VADDR);
-}
-
-inline const u32 VirtualAddressFromPhysical_IO(const u32 address) {
-    return (address + 0x0EB00000);
-}
+/// Converts a physical address to virtual address
+u32 PhysicalToVirtualAddress(const u32 addr);
 
-inline const u32 VirtualAddressFromPhysical_VRAM(const u32 address) {
-    return (address + 0x07000000);
-}
+/// Converts a virtual address to physical address
+u32 VirtualToPhysicalAddress(const u32 addr);
 
 } // namespace

+ 36 - 32
src/core/mem_map_funcs.cpp

@@ -17,37 +17,44 @@ std::map<u32, MemoryBlock> g_heap_map;
 std::map<u32, MemoryBlock> g_heap_gsp_map;
 std::map<u32, MemoryBlock> g_shared_map;
 
-/// Convert a physical address (or firmware-specific virtual address) to primary virtual address
-u32 _VirtualAddress(const u32 addr) {
-    // Our memory interface read/write functions assume virtual addresses. Put any physical address 
-    // to virtual address translations here. This is obviously quite hacky... But we're not doing 
-    // any MMU emulation yet or anything
-    if ((addr >= FCRAM_PADDR) && (addr < FCRAM_PADDR_END)) {
-        return VirtualAddressFromPhysical_FCRAM(addr);
-
-    // Virtual address mapping FW0B
-    } else if ((addr >= FCRAM_VADDR_FW0B) && (addr < FCRAM_VADDR_FW0B_END)) {
-        return VirtualAddressFromPhysical_FCRAM(addr);
-
-    // Hardware IO
-    // TODO(bunnei): FixMe
-    // This isn't going to work... The physical address of HARDWARE_IO conflicts with the virtual 
-    // address of shared memory.
-    //} else if ((addr >= HARDWARE_IO_PADDR) && (addr < HARDWARE_IO_PADDR_END)) {
-    //    return (addr + 0x0EB00000);
+/// Convert a physical address to virtual address
+u32 PhysicalToVirtualAddress(const u32 addr) {
+    // Our memory interface read/write functions assume virtual addresses. Put any physical address
+    // to virtual address translations here. This is quite hacky, but necessary until we implement
+    // proper MMU emulation.
+    // TODO: Screw it, I'll let bunnei figure out how to do this properly.
+    if ((addr >= VRAM_PADDR) && (addr < VRAM_PADDR_END)) {
+        return addr - VRAM_PADDR + VRAM_VADDR;
+    }else if ((addr >= FCRAM_PADDR) && (addr < FCRAM_PADDR_END)) {
+        return addr - FCRAM_PADDR + FCRAM_VADDR;
+    }
+
+    ERROR_LOG(MEMMAP, "Unknown physical address @ 0x%08x", addr);
+    return addr;
+}
 
+/// Convert a physical address to virtual address
+u32 VirtualToPhysicalAddress(const u32 addr) {
+    // Our memory interface read/write functions assume virtual addresses. Put any physical address
+    // to virtual address translations here. This is quite hacky, but necessary until we implement
+    // proper MMU emulation.
+    // TODO: Screw it, I'll let bunnei figure out how to do this properly.
+    if ((addr >= VRAM_VADDR) && (addr < VRAM_VADDR_END)) {
+        return addr - 0x07000000;
+    } else if ((addr >= FCRAM_VADDR) && (addr < FCRAM_VADDR_END)) {
+        return addr - FCRAM_VADDR + FCRAM_PADDR;
     }
+
+    ERROR_LOG(MEMMAP, "Unknown virtual address @ 0x%08x", addr);
     return addr;
 }
 
 template <typename T>
-inline void Read(T &var, const u32 addr) {
+inline void Read(T &var, const u32 vaddr) {
     // TODO: Figure out the fastest order of tests for both read and write (they are probably different).
     // TODO: Make sure this represents the mirrors in a correct way.
     // Could just do a base-relative read, too.... TODO
 
-    const u32 vaddr = _VirtualAddress(addr);
-
     // Kernel memory command buffer
     if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) {
         var = *((const T*)&g_kernel_mem[vaddr & KERNEL_MEMORY_MASK]);
@@ -91,9 +98,8 @@ inline void Read(T &var, const u32 addr) {
 }
 
 template <typename T>
-inline void Write(u32 addr, const T data) {
-    u32 vaddr = _VirtualAddress(addr);
-    
+inline void Write(u32 vaddr, const T data) {
+
     // Kernel memory command buffer
     if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) {
         *(T*)&g_kernel_mem[vaddr & KERNEL_MEMORY_MASK] = data;
@@ -133,16 +139,14 @@ inline void Write(u32 addr, const T data) {
     //    _assert_msg_(MEMMAP, false, "umimplemented write to Configuration Memory");
     //} else if ((vaddr & 0xFFFFF000) == 0x1FF81000) {
     //    _assert_msg_(MEMMAP, false, "umimplemented write to shared page");
-    
+
     // Error out...
     } else {
         ERROR_LOG(MEMMAP, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, vaddr);
     }
 }
 
-u8 *GetPointer(const u32 addr) {
-    const u32 vaddr = _VirtualAddress(addr);
-
+u8 *GetPointer(const u32 vaddr) {
     // Kernel memory command buffer
     if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) {
         return g_kernel_mem + (vaddr & KERNEL_MEMORY_MASK);
@@ -185,12 +189,12 @@ u8 *GetPointer(const u32 addr) {
  */
 u32 MapBlock_Heap(u32 size, u32 operation, u32 permissions) {
     MemoryBlock block;
-    
+
     block.base_address  = HEAP_VADDR;
     block.size          = size;
     block.operation     = operation;
     block.permissions   = permissions;
-    
+
     if (g_heap_map.size() > 0) {
         const MemoryBlock last_block = g_heap_map.rbegin()->second;
         block.address = last_block.address + last_block.size;
@@ -208,12 +212,12 @@ u32 MapBlock_Heap(u32 size, u32 operation, u32 permissions) {
  */
 u32 MapBlock_HeapGSP(u32 size, u32 operation, u32 permissions) {
     MemoryBlock block;
-    
+
     block.base_address  = HEAP_GSP_VADDR;
     block.size          = size;
     block.operation     = operation;
     block.permissions   = permissions;
-    
+
     if (g_heap_gsp_map.size() > 0) {
         const MemoryBlock last_block = g_heap_gsp_map.rbegin()->second;
         block.address = last_block.address + last_block.size;

+ 1 - 1
src/video_core/pica.h

@@ -45,7 +45,7 @@ struct Regs {
     INSERT_PADDING_WORDS(0x41);
 
     BitField<0, 24, u32> viewport_size_x;
-    INSERT_PADDING_WORDS(1);
+    INSERT_PADDING_WORDS(0x1);
     BitField<0, 24, u32> viewport_size_y;
 
     INSERT_PADDING_WORDS(0x1bc);

+ 7 - 7
src/video_core/renderer_opengl/renderer_opengl.cpp

@@ -81,20 +81,20 @@ void RendererOpenGL::RenderXFB(const common::Rect& src_rect, const common::Rect&
     const auto& framebuffer_top = GPU::g_regs.framebuffer_config[0];
     const auto& framebuffer_sub = GPU::g_regs.framebuffer_config[1];
     const u32 active_fb_top = (framebuffer_top.active_fb == 1)
-                                ? framebuffer_top.address_left2
-                                : framebuffer_top.address_left1;
+                                ? Memory::PhysicalToVirtualAddress(framebuffer_top.address_left2)
+                                : Memory::PhysicalToVirtualAddress(framebuffer_top.address_left1);
     const u32 active_fb_sub = (framebuffer_sub.active_fb == 1)
-                                ? framebuffer_sub.address_left2
-                                : framebuffer_sub.address_left1;
+                                ? Memory::PhysicalToVirtualAddress(framebuffer_sub.address_left2)
+                                : Memory::PhysicalToVirtualAddress(framebuffer_sub.address_left1);
 
     DEBUG_LOG(GPU, "RenderXFB: 0x%08x bytes from 0x%08x(%dx%d), fmt %x",
               framebuffer_top.stride * framebuffer_top.height,
-              GPU::GetFramebufferAddr(active_fb_top), (int)framebuffer_top.width,
+              active_fb_top, (int)framebuffer_top.width,
               (int)framebuffer_top.height, (int)framebuffer_top.format);
 
     // TODO: This should consider the GPU registers for framebuffer width, height and stride.
-    FlipFramebuffer(GPU::GetFramebufferPointer(active_fb_top), m_xfb_top_flipped);
-    FlipFramebuffer(GPU::GetFramebufferPointer(active_fb_sub), m_xfb_bottom_flipped);
+    FlipFramebuffer(Memory::GetPointer(active_fb_top), m_xfb_top_flipped);
+    FlipFramebuffer(Memory::GetPointer(active_fb_sub), m_xfb_bottom_flipped);
 
     // Blit the top framebuffer
     // ------------------------