aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hw/gpu.h
diff options
context:
space:
mode:
authorGravatar Tony Wasserka <NeoBrainX@gmail.com>2014-07-16 11:24:09 +0200
committerGravatar Tony Wasserka <NeoBrainX@gmail.com>2014-07-23 00:33:08 +0200
commit75775e9ef41248592cb2c27ae69737e46499e705 (patch)
tree9bff36e351d33fd3dcf40ccfb17e23f4916a23a3 /src/core/hw/gpu.h
parent357d893b2642e91d5c44a7da7ccdcbe837f46b0a (diff)
GPU: Make use of RegisterSet.
Diffstat (limited to 'src/core/hw/gpu.h')
-rw-r--r--src/core/hw/gpu.h136
1 files changed, 71 insertions, 65 deletions
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h
index b66cf4a3..ce524bd0 100644
--- a/src/core/hw/gpu.h
+++ b/src/core/hw/gpu.h
@@ -6,54 +6,31 @@
#include "common/common_types.h"
#include "common/bit_field.h"
+#include "common/register_set.h"
namespace GPU {
static const u32 kFrameCycles = 268123480 / 60; ///< 268MHz / 60 frames per second
static const u32 kFrameTicks = kFrameCycles / 3; ///< Approximate number of instructions/frame
-struct Registers {
+// MMIO region 0x1EFxxxxx
+struct Regs {
enum Id : u32 {
- MemoryFillStart1 = 0x1EF00010,
- MemoryFillEnd1 = 0x1EF00014,
- MemoryFillSize1 = 0x1EF00018,
- MemoryFillValue1 = 0x1EF0001C,
- MemoryFillStart2 = 0x1EF00020,
- MemoryFillEnd2 = 0x1EF00024,
- MemoryFillSize2 = 0x1EF00028,
- MemoryFillValue2 = 0x1EF0002C,
-
- 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,
- DisplayOutputBufferSize = 0x1EF00C08,
- DisplayInputBufferSize = 0x1EF00C0C,
- DisplayTransferFlags = 0x1EF00C10,
- // Unknown??
- DisplayTriggerTransfer = 0x1EF00C18,
-
- CommandListSize = 0x1EF018E0,
- CommandListAddress = 0x1EF018E8,
- ProcessCommandList = 0x1EF018F0,
+ MemoryFill = 0x00004, // + 5,6,7; second block at 8-11
+
+ FramebufferTop = 0x00117, // + 11a,11b,11c,11d(?),11e...126
+ FramebufferBottom = 0x00157, // + 15a,15b,15c,15d(?),15e...166
+
+ DisplayTransfer = 0x00300, // + 301,302,303,304,305,306
+
+ CommandProcessor = 0x00638, // + 63a,63c
+
+ NumIds = 0x01000
};
+ template<Id id>
+ union Struct;
+
enum class FramebufferFormat : u32 {
RGBA8 = 0,
RGB8 = 1,
@@ -62,7 +39,11 @@ struct Registers {
RGBA4 = 4,
};
- struct MemoryFillConfig {
+};
+
+template<>
+union Regs::Struct<Regs::MemoryFill> {
+ struct {
u32 address_start;
u32 address_end; // ?
u32 size;
@@ -75,21 +56,15 @@ struct Registers {
inline u32 GetEndAddress() const {
return address_end * 8;
}
- };
-
- MemoryFillConfig memory_fill[2];
+ } data;
+};
+static_assert(sizeof(Regs::Struct<Regs::MemoryFill>) == 0x10, "Structure size and register block length don't match");
- // TODO: Move these into the framebuffer struct
- u32 framebuffer_top_left_1;
- u32 framebuffer_top_left_2;
- u32 framebuffer_top_right_1;
- u32 framebuffer_top_right_2;
- u32 framebuffer_sub_left_1;
- u32 framebuffer_sub_left_2;
- u32 framebuffer_sub_right_1;
- u32 framebuffer_sub_right_2;
+template<>
+union Regs::Struct<Regs::FramebufferTop> {
+ using Format = Regs::FramebufferFormat;
- struct FrameBufferConfig {
+ struct {
union {
u32 size;
@@ -97,22 +72,43 @@ struct Registers {
BitField<16, 16, u32> height;
};
+ u32 pad0[2];
+
+ u32 address_left1;
+ u32 address_left2;
+
union {
u32 format;
- BitField< 0, 3, FramebufferFormat> color_format;
+ BitField< 0, 3, Format> color_format;
};
+ u32 pad1;
+
union {
u32 active_fb;
BitField<0, 1, u32> second_fb_active;
};
+ u32 pad2[5];
+
u32 stride;
- };
- FrameBufferConfig top_framebuffer;
- FrameBufferConfig sub_framebuffer;
+
+ u32 address_right1;
+ u32 address_right2;
+ } data;
+};
+template<>
+union Regs::Struct<Regs::FramebufferBottom> {
+ using Type = decltype(Regs::Struct<Regs::FramebufferTop>::data);
+ Type data;
+};
+static_assert(sizeof(Regs::Struct<Regs::FramebufferTop>) == 0x40, "Structure size and register block length don't match");
+
+template<>
+union Regs::Struct<Regs::DisplayTransfer> {
+ using Format = Regs::FramebufferFormat;
struct {
u32 input_address;
@@ -144,21 +140,31 @@ struct Registers {
u32 flags;
BitField< 0, 1, u32> flip_data;
- BitField< 8, 3, FramebufferFormat> input_format;
- BitField<12, 3, FramebufferFormat> output_format;
+ BitField< 8, 3, Format> input_format;
+ BitField<12, 3, Format> output_format;
BitField<16, 1, u32> output_tiled;
};
u32 unknown;
u32 trigger;
- } display_transfer;
+ } data;
+};
+static_assert(sizeof(Regs::Struct<Regs::DisplayTransfer>) == 0x1C, "Structure size and register block length don't match");
- u32 command_list_size;
- u32 command_list_address;
- u32 command_processing_enabled;
+template<>
+union Regs::Struct<Regs::CommandProcessor> {
+ struct {
+ u32 size;
+ u32 pad0;
+ u32 address;
+ u32 pad1;
+ u32 trigger;
+ } data;
};
+static_assert(sizeof(Regs::Struct<Regs::CommandProcessor>) == 0x14, "Structure size and register block length don't match");
+
-extern Registers g_regs;
+extern RegisterSet<u32, Regs> g_regs;
enum {
TOP_ASPECT_X = 0x5,
@@ -208,7 +214,7 @@ enum FramebufferLocation {
/**
* Sets whether the framebuffers are in the GSP heap (FCRAM) or VRAM
- * @param
+ * @param
*/
void SetFramebufferLocation(const FramebufferLocation mode);