aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hw
diff options
context:
space:
mode:
authorGravatar Tony Wasserka <NeoBrainX@gmail.com>2014-07-11 19:10:08 +0200
committerGravatar Tony Wasserka <NeoBrainX@gmail.com>2014-07-23 00:33:08 +0200
commit0b4055c1520fbe7f697d2f1f93a85b559504cca4 (patch)
treeee387998414415a41a83628ab9d61772a2c494aa /src/core/hw
parentbbc6f314eb56ab1cf0a4b800750130de515cdd0f (diff)
GPU: Add proper framebuffer register handling.
Diffstat (limited to 'src/core/hw')
-rw-r--r--src/core/hw/gpu.cpp53
-rw-r--r--src/core/hw/gpu.h63
2 files changed, 105 insertions, 11 deletions
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 <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;
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;
};