From 0b4055c1520fbe7f697d2f1f93a85b559504cca4 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Fri, 11 Jul 2014 19:10:08 +0200 Subject: GPU: Add proper framebuffer register handling. --- src/core/hw/gpu.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++- src/core/hw/gpu.h | 63 ++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 105 insertions(+), 11 deletions(-) (limited to 'src/core/hw') diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index e05e1b02..fad3439c 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp @@ -84,6 +84,10 @@ const u8* GetFramebufferPointer(const u32 address) { template inline void Read(T &var, const u32 addr) { switch (addr) { + case Registers::FramebufferTopSize: + var = g_regs.top_framebuffer.size; + break; + case Registers::FramebufferTopLeft1: var = g_regs.framebuffer_top_left_1; break; @@ -92,6 +96,18 @@ inline void Read(T &var, const u32 addr) { var = g_regs.framebuffer_top_left_2; break; + case Registers::FramebufferTopFormat: + var = g_regs.top_framebuffer.format; + break; + + case Registers::FramebufferTopSwapBuffers: + var = g_regs.top_framebuffer.active_fb; + break; + + case Registers::FramebufferTopStride: + var = g_regs.top_framebuffer.stride; + break; + case Registers::FramebufferTopRight1: var = g_regs.framebuffer_top_right_1; break; @@ -100,6 +116,10 @@ inline void Read(T &var, const u32 addr) { var = g_regs.framebuffer_top_right_2; break; + case Registers::FramebufferSubSize: + var = g_regs.sub_framebuffer.size; + break; + case Registers::FramebufferSubLeft1: var = g_regs.framebuffer_sub_left_1; break; @@ -108,6 +128,26 @@ inline void Read(T &var, const u32 addr) { var = g_regs.framebuffer_sub_right_1; break; + case Registers::FramebufferSubFormat: + var = g_regs.sub_framebuffer.format; + break; + + case Registers::FramebufferSubSwapBuffers: + var = g_regs.sub_framebuffer.active_fb; + break; + + case Registers::FramebufferSubStride: + var = g_regs.sub_framebuffer.stride; + break; + + case Registers::FramebufferSubLeft2: + var = g_regs.framebuffer_sub_left_2; + break; + + case Registers::FramebufferSubRight2: + var = g_regs.framebuffer_sub_right_2; + break; + case Registers::DisplayInputBufferAddr: var = g_regs.display_transfer.input_address; break; @@ -154,6 +194,17 @@ inline void Read(T &var, const u32 addr) { template inline void Write(u32 addr, const T data) { switch (static_cast(addr)) { + // TODO: Framebuffer registers!! + case Registers::FramebufferTopSwapBuffers: + g_regs.top_framebuffer.active_fb = data; + // TODO: Not sure if this should only be done upon a change! + break; + + case Registers::FramebufferSubSwapBuffers: + g_regs.sub_framebuffer.active_fb = data; + // TODO: Not sure if this should only be done upon a change! + break; + case Registers::DisplayInputBufferAddr: g_regs.display_transfer.input_address = data; break; @@ -195,7 +246,7 @@ inline void Write(u32 addr, const T data) { g_regs.display_transfer.output_height * g_regs.display_transfer.output_width * 4, g_regs.display_transfer.GetPhysicalInputAddress(), (int)g_regs.display_transfer.input_width, (int)g_regs.display_transfer.input_height, g_regs.display_transfer.GetPhysicalOutputAddress(), (int)g_regs.display_transfer.output_width, (int)g_regs.display_transfer.output_height, - (int)g_regs.display_transfer.output_format); + (int)g_regs.display_transfer.output_format.Value()); } break; diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index 29eb7ed8..50c36081 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -14,14 +14,23 @@ static const u32 kFrameTicks = kFrameCycles / 3; ///< Approximate number of i struct Registers { enum Id : u32 { - FramebufferTopLeft1 = 0x1EF00468, // Main LCD, first framebuffer for 3D left - FramebufferTopLeft2 = 0x1EF0046C, // Main LCD, second framebuffer for 3D left - FramebufferTopRight1 = 0x1EF00494, // Main LCD, first framebuffer for 3D right - FramebufferTopRight2 = 0x1EF00498, // Main LCD, second framebuffer for 3D right - FramebufferSubLeft1 = 0x1EF00568, // Sub LCD, first framebuffer - FramebufferSubLeft2 = 0x1EF0056C, // Sub LCD, second framebuffer - FramebufferSubRight1 = 0x1EF00594, // Sub LCD, unused first framebuffer - FramebufferSubRight2 = 0x1EF00598, // Sub LCD, unused second framebuffer + FramebufferTopSize = 0x1EF0045C, + FramebufferTopLeft1 = 0x1EF00468, // Main LCD, first framebuffer for 3D left + FramebufferTopLeft2 = 0x1EF0046C, // Main LCD, second framebuffer for 3D left + FramebufferTopFormat = 0x1EF00470, + FramebufferTopSwapBuffers = 0x1EF00478, + FramebufferTopStride = 0x1EF00490, // framebuffer row stride? + FramebufferTopRight1 = 0x1EF00494, // Main LCD, first framebuffer for 3D right + FramebufferTopRight2 = 0x1EF00498, // Main LCD, second framebuffer for 3D right + + FramebufferSubSize = 0x1EF0055C, + FramebufferSubLeft1 = 0x1EF00568, // Sub LCD, first framebuffer + FramebufferSubLeft2 = 0x1EF0056C, // Sub LCD, second framebuffer + FramebufferSubFormat = 0x1EF00570, + FramebufferSubSwapBuffers = 0x1EF00578, + FramebufferSubStride = 0x1EF00590, // framebuffer row stride? + FramebufferSubRight1 = 0x1EF00594, // Sub LCD, unused first framebuffer + FramebufferSubRight2 = 0x1EF00598, // Sub LCD, unused second framebuffer DisplayInputBufferAddr = 0x1EF00C00, DisplayOutputBufferAddr = 0x1EF00C04, @@ -36,6 +45,15 @@ struct Registers { ProcessCommandList = 0x1EF018F0, }; + enum class FramebufferFormat : u32 { + RGBA8 = 0, + RGB8 = 1, + RGB565 = 2, + RGB5A1 = 3, + RGBA4 = 4, + }; + + // TODO: Move these into the framebuffer struct u32 framebuffer_top_left_1; u32 framebuffer_top_left_2; u32 framebuffer_top_right_1; @@ -45,6 +63,31 @@ struct Registers { u32 framebuffer_sub_right_1; u32 framebuffer_sub_right_2; + struct FrameBufferConfig { + union { + u32 size; + + BitField< 0, 16, u32> width; + BitField<16, 16, u32> height; + }; + + union { + u32 format; + + BitField< 0, 3, FramebufferFormat> color_format; + }; + + union { + u32 active_fb; + + BitField<0, 1, u32> second_fb_active; + }; + + u32 stride; + }; + FrameBufferConfig top_framebuffer; + FrameBufferConfig sub_framebuffer; + struct { u32 input_address; u32 output_address; @@ -75,8 +118,8 @@ struct Registers { u32 flags; BitField< 0, 1, u32> flip_data; - BitField< 8, 3, u32> input_format; - BitField<12, 3, u32> output_format; + BitField< 8, 3, FramebufferFormat> input_format; + BitField<12, 3, FramebufferFormat> output_format; BitField<16, 1, u32> output_tiled; }; -- cgit v1.2.3