mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-11-04 20:44:02 +08:00 
			
		
		
		
	GPU: Add proper framebuffer register handling.
This commit is contained in:
		
							parent
							
								
									bbc6f314eb
								
							
						
					
					
						commit
						0b4055c152
					
				@ -84,6 +84,10 @@ const u8* GetFramebufferPointer(const u32 address) {
 | 
				
			|||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
inline void Read(T &var, const u32 addr) {
 | 
					inline void Read(T &var, const u32 addr) {
 | 
				
			||||||
    switch (addr) {
 | 
					    switch (addr) {
 | 
				
			||||||
 | 
					    case Registers::FramebufferTopSize:
 | 
				
			||||||
 | 
					        var = g_regs.top_framebuffer.size;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case Registers::FramebufferTopLeft1:
 | 
					    case Registers::FramebufferTopLeft1:
 | 
				
			||||||
        var = g_regs.framebuffer_top_left_1;
 | 
					        var = g_regs.framebuffer_top_left_1;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -92,6 +96,18 @@ inline void Read(T &var, const u32 addr) {
 | 
				
			|||||||
        var = g_regs.framebuffer_top_left_2;
 | 
					        var = g_regs.framebuffer_top_left_2;
 | 
				
			||||||
        break;
 | 
					        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:
 | 
					    case Registers::FramebufferTopRight1:
 | 
				
			||||||
        var = g_regs.framebuffer_top_right_1;
 | 
					        var = g_regs.framebuffer_top_right_1;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -100,6 +116,10 @@ inline void Read(T &var, const u32 addr) {
 | 
				
			|||||||
        var = g_regs.framebuffer_top_right_2;
 | 
					        var = g_regs.framebuffer_top_right_2;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case Registers::FramebufferSubSize:
 | 
				
			||||||
 | 
					        var = g_regs.sub_framebuffer.size;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case Registers::FramebufferSubLeft1:
 | 
					    case Registers::FramebufferSubLeft1:
 | 
				
			||||||
        var = g_regs.framebuffer_sub_left_1;
 | 
					        var = g_regs.framebuffer_sub_left_1;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -108,6 +128,26 @@ inline void Read(T &var, const u32 addr) {
 | 
				
			|||||||
        var = g_regs.framebuffer_sub_right_1;
 | 
					        var = g_regs.framebuffer_sub_right_1;
 | 
				
			||||||
        break;
 | 
					        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:
 | 
					    case Registers::DisplayInputBufferAddr:
 | 
				
			||||||
        var = g_regs.display_transfer.input_address;
 | 
					        var = g_regs.display_transfer.input_address;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -154,6 +194,17 @@ inline void Read(T &var, const u32 addr) {
 | 
				
			|||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
inline void Write(u32 addr, const T data) {
 | 
					inline void Write(u32 addr, const T data) {
 | 
				
			||||||
    switch (static_cast<Registers::Id>(addr)) {
 | 
					    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:
 | 
					    case Registers::DisplayInputBufferAddr:
 | 
				
			||||||
        g_regs.display_transfer.input_address = data;
 | 
					        g_regs.display_transfer.input_address = data;
 | 
				
			||||||
        break;
 | 
					        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.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.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,
 | 
					                      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;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -14,14 +14,23 @@ static const u32 kFrameTicks    = kFrameCycles / 3; ///< Approximate number of i
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct Registers {
 | 
					struct Registers {
 | 
				
			||||||
    enum Id : u32 {
 | 
					    enum Id : u32 {
 | 
				
			||||||
        FramebufferTopLeft1     = 0x1EF00468,   // Main LCD, first framebuffer for 3D left
 | 
					        FramebufferTopSize        = 0x1EF0045C,
 | 
				
			||||||
        FramebufferTopLeft2     = 0x1EF0046C,   // Main LCD, second framebuffer for 3D left
 | 
					        FramebufferTopLeft1       = 0x1EF00468,   // Main LCD, first framebuffer for 3D left
 | 
				
			||||||
        FramebufferTopRight1    = 0x1EF00494,   // Main LCD, first framebuffer for 3D right
 | 
					        FramebufferTopLeft2       = 0x1EF0046C,   // Main LCD, second framebuffer for 3D left
 | 
				
			||||||
        FramebufferTopRight2    = 0x1EF00498,   // Main LCD, second framebuffer for 3D right
 | 
					        FramebufferTopFormat      = 0x1EF00470,
 | 
				
			||||||
        FramebufferSubLeft1     = 0x1EF00568,   // Sub LCD, first framebuffer
 | 
					        FramebufferTopSwapBuffers = 0x1EF00478,
 | 
				
			||||||
        FramebufferSubLeft2     = 0x1EF0056C,   // Sub LCD, second framebuffer
 | 
					        FramebufferTopStride      = 0x1EF00490,   // framebuffer row stride?
 | 
				
			||||||
        FramebufferSubRight1    = 0x1EF00594,   // Sub LCD, unused first framebuffer
 | 
					        FramebufferTopRight1      = 0x1EF00494,   // Main LCD, first framebuffer for 3D right
 | 
				
			||||||
        FramebufferSubRight2    = 0x1EF00598,   // Sub LCD, unused second framebuffer
 | 
					        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,
 | 
					        DisplayInputBufferAddr  = 0x1EF00C00,
 | 
				
			||||||
        DisplayOutputBufferAddr = 0x1EF00C04,
 | 
					        DisplayOutputBufferAddr = 0x1EF00C04,
 | 
				
			||||||
@ -36,6 +45,15 @@ struct Registers {
 | 
				
			|||||||
        ProcessCommandList      = 0x1EF018F0,
 | 
					        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_1;
 | 
				
			||||||
    u32 framebuffer_top_left_2;
 | 
					    u32 framebuffer_top_left_2;
 | 
				
			||||||
    u32 framebuffer_top_right_1;
 | 
					    u32 framebuffer_top_right_1;
 | 
				
			||||||
@ -45,6 +63,31 @@ struct Registers {
 | 
				
			|||||||
    u32 framebuffer_sub_right_1;
 | 
					    u32 framebuffer_sub_right_1;
 | 
				
			||||||
    u32 framebuffer_sub_right_2;
 | 
					    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 {
 | 
					    struct {
 | 
				
			||||||
        u32 input_address;
 | 
					        u32 input_address;
 | 
				
			||||||
        u32 output_address;
 | 
					        u32 output_address;
 | 
				
			||||||
@ -75,8 +118,8 @@ struct Registers {
 | 
				
			|||||||
            u32 flags;
 | 
					            u32 flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            BitField< 0, 1, u32> flip_data;
 | 
					            BitField< 0, 1, u32> flip_data;
 | 
				
			||||||
            BitField< 8, 3, u32> input_format;
 | 
					            BitField< 8, 3, FramebufferFormat> input_format;
 | 
				
			||||||
            BitField<12, 3, u32> output_format;
 | 
					            BitField<12, 3, FramebufferFormat> output_format;
 | 
				
			||||||
            BitField<16, 1, u32> output_tiled;
 | 
					            BitField<16, 1, u32> output_tiled;
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user