GPU: Add proper framebuffer register handling.
This commit is contained in:
		| @@ -84,6 +84,10 @@ const u8* GetFramebufferPointer(const u32 address) { | ||||
| template <typename T> | ||||
| 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 <typename T> | ||||
| inline void Write(u32 addr, const T data) { | ||||
|     switch (static_cast<Registers::Id>(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; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|         }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user