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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Reference in New Issue