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>
 | 
			
		||||
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,12 +14,21 @@ static const u32 kFrameTicks    = kFrameCycles / 3; ///< Approximate number of i
 | 
			
		||||
 | 
			
		||||
struct Registers {
 | 
			
		||||
    enum Id : u32 {
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user