diff options
| author | 2014-07-16 11:24:09 +0200 | |
|---|---|---|
| committer | 2014-07-23 00:33:08 +0200 | |
| commit | 75775e9ef41248592cb2c27ae69737e46499e705 (patch) | |
| tree | 9bff36e351d33fd3dcf40ccfb17e23f4916a23a3 /src/core/hw/gpu.h | |
| parent | GPU: Make framebuffer code format-aware. (diff) | |
| download | yuzu-75775e9ef41248592cb2c27ae69737e46499e705.tar.gz yuzu-75775e9ef41248592cb2c27ae69737e46499e705.tar.xz yuzu-75775e9ef41248592cb2c27ae69737e46499e705.zip | |
GPU: Make use of RegisterSet.
Diffstat (limited to 'src/core/hw/gpu.h')
| -rw-r--r-- | src/core/hw/gpu.h | 136 |
1 files changed, 71 insertions, 65 deletions
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index b66cf4a37..ce524bd02 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h | |||
| @@ -6,54 +6,31 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "common/bit_field.h" | 8 | #include "common/bit_field.h" |
| 9 | #include "common/register_set.h" | ||
| 9 | 10 | ||
| 10 | namespace GPU { | 11 | namespace GPU { |
| 11 | 12 | ||
| 12 | static const u32 kFrameCycles = 268123480 / 60; ///< 268MHz / 60 frames per second | 13 | static const u32 kFrameCycles = 268123480 / 60; ///< 268MHz / 60 frames per second |
| 13 | static const u32 kFrameTicks = kFrameCycles / 3; ///< Approximate number of instructions/frame | 14 | static const u32 kFrameTicks = kFrameCycles / 3; ///< Approximate number of instructions/frame |
| 14 | 15 | ||
| 15 | struct Registers { | 16 | // MMIO region 0x1EFxxxxx |
| 17 | struct Regs { | ||
| 16 | enum Id : u32 { | 18 | enum Id : u32 { |
| 17 | MemoryFillStart1 = 0x1EF00010, | 19 | MemoryFill = 0x00004, // + 5,6,7; second block at 8-11 |
| 18 | MemoryFillEnd1 = 0x1EF00014, | 20 | |
| 19 | MemoryFillSize1 = 0x1EF00018, | 21 | FramebufferTop = 0x00117, // + 11a,11b,11c,11d(?),11e...126 |
| 20 | MemoryFillValue1 = 0x1EF0001C, | 22 | FramebufferBottom = 0x00157, // + 15a,15b,15c,15d(?),15e...166 |
| 21 | MemoryFillStart2 = 0x1EF00020, | 23 | |
| 22 | MemoryFillEnd2 = 0x1EF00024, | 24 | DisplayTransfer = 0x00300, // + 301,302,303,304,305,306 |
| 23 | MemoryFillSize2 = 0x1EF00028, | 25 | |
| 24 | MemoryFillValue2 = 0x1EF0002C, | 26 | CommandProcessor = 0x00638, // + 63a,63c |
| 25 | 27 | ||
| 26 | FramebufferTopSize = 0x1EF0045C, | 28 | NumIds = 0x01000 |
| 27 | FramebufferTopLeft1 = 0x1EF00468, // Main LCD, first framebuffer for 3D left | ||
| 28 | FramebufferTopLeft2 = 0x1EF0046C, // Main LCD, second framebuffer for 3D left | ||
| 29 | FramebufferTopFormat = 0x1EF00470, | ||
| 30 | FramebufferTopSwapBuffers = 0x1EF00478, | ||
| 31 | FramebufferTopStride = 0x1EF00490, // framebuffer row stride? | ||
| 32 | FramebufferTopRight1 = 0x1EF00494, // Main LCD, first framebuffer for 3D right | ||
| 33 | FramebufferTopRight2 = 0x1EF00498, // Main LCD, second framebuffer for 3D right | ||
| 34 | |||
| 35 | FramebufferSubSize = 0x1EF0055C, | ||
| 36 | FramebufferSubLeft1 = 0x1EF00568, // Sub LCD, first framebuffer | ||
| 37 | FramebufferSubLeft2 = 0x1EF0056C, // Sub LCD, second framebuffer | ||
| 38 | FramebufferSubFormat = 0x1EF00570, | ||
| 39 | FramebufferSubSwapBuffers = 0x1EF00578, | ||
| 40 | FramebufferSubStride = 0x1EF00590, // framebuffer row stride? | ||
| 41 | FramebufferSubRight1 = 0x1EF00594, // Sub LCD, unused first framebuffer | ||
| 42 | FramebufferSubRight2 = 0x1EF00598, // Sub LCD, unused second framebuffer | ||
| 43 | |||
| 44 | DisplayInputBufferAddr = 0x1EF00C00, | ||
| 45 | DisplayOutputBufferAddr = 0x1EF00C04, | ||
| 46 | DisplayOutputBufferSize = 0x1EF00C08, | ||
| 47 | DisplayInputBufferSize = 0x1EF00C0C, | ||
| 48 | DisplayTransferFlags = 0x1EF00C10, | ||
| 49 | // Unknown?? | ||
| 50 | DisplayTriggerTransfer = 0x1EF00C18, | ||
| 51 | |||
| 52 | CommandListSize = 0x1EF018E0, | ||
| 53 | CommandListAddress = 0x1EF018E8, | ||
| 54 | ProcessCommandList = 0x1EF018F0, | ||
| 55 | }; | 29 | }; |
| 56 | 30 | ||
| 31 | template<Id id> | ||
| 32 | union Struct; | ||
| 33 | |||
| 57 | enum class FramebufferFormat : u32 { | 34 | enum class FramebufferFormat : u32 { |
| 58 | RGBA8 = 0, | 35 | RGBA8 = 0, |
| 59 | RGB8 = 1, | 36 | RGB8 = 1, |
| @@ -62,7 +39,11 @@ struct Registers { | |||
| 62 | RGBA4 = 4, | 39 | RGBA4 = 4, |
| 63 | }; | 40 | }; |
| 64 | 41 | ||
| 65 | struct MemoryFillConfig { | 42 | }; |
| 43 | |||
| 44 | template<> | ||
| 45 | union Regs::Struct<Regs::MemoryFill> { | ||
| 46 | struct { | ||
| 66 | u32 address_start; | 47 | u32 address_start; |
| 67 | u32 address_end; // ? | 48 | u32 address_end; // ? |
| 68 | u32 size; | 49 | u32 size; |
| @@ -75,21 +56,15 @@ struct Registers { | |||
| 75 | inline u32 GetEndAddress() const { | 56 | inline u32 GetEndAddress() const { |
| 76 | return address_end * 8; | 57 | return address_end * 8; |
| 77 | } | 58 | } |
| 78 | }; | 59 | } data; |
| 79 | 60 | }; | |
| 80 | MemoryFillConfig memory_fill[2]; | 61 | static_assert(sizeof(Regs::Struct<Regs::MemoryFill>) == 0x10, "Structure size and register block length don't match"); |
| 81 | 62 | ||
| 82 | // TODO: Move these into the framebuffer struct | 63 | template<> |
| 83 | u32 framebuffer_top_left_1; | 64 | union Regs::Struct<Regs::FramebufferTop> { |
| 84 | u32 framebuffer_top_left_2; | 65 | using Format = Regs::FramebufferFormat; |
| 85 | u32 framebuffer_top_right_1; | ||
| 86 | u32 framebuffer_top_right_2; | ||
| 87 | u32 framebuffer_sub_left_1; | ||
| 88 | u32 framebuffer_sub_left_2; | ||
| 89 | u32 framebuffer_sub_right_1; | ||
| 90 | u32 framebuffer_sub_right_2; | ||
| 91 | 66 | ||
| 92 | struct FrameBufferConfig { | 67 | struct { |
| 93 | union { | 68 | union { |
| 94 | u32 size; | 69 | u32 size; |
| 95 | 70 | ||
| @@ -97,22 +72,43 @@ struct Registers { | |||
| 97 | BitField<16, 16, u32> height; | 72 | BitField<16, 16, u32> height; |
| 98 | }; | 73 | }; |
| 99 | 74 | ||
| 75 | u32 pad0[2]; | ||
| 76 | |||
| 77 | u32 address_left1; | ||
| 78 | u32 address_left2; | ||
| 79 | |||
| 100 | union { | 80 | union { |
| 101 | u32 format; | 81 | u32 format; |
| 102 | 82 | ||
| 103 | BitField< 0, 3, FramebufferFormat> color_format; | 83 | BitField< 0, 3, Format> color_format; |
| 104 | }; | 84 | }; |
| 105 | 85 | ||
| 86 | u32 pad1; | ||
| 87 | |||
| 106 | union { | 88 | union { |
| 107 | u32 active_fb; | 89 | u32 active_fb; |
| 108 | 90 | ||
| 109 | BitField<0, 1, u32> second_fb_active; | 91 | BitField<0, 1, u32> second_fb_active; |
| 110 | }; | 92 | }; |
| 111 | 93 | ||
| 94 | u32 pad2[5]; | ||
| 95 | |||
| 112 | u32 stride; | 96 | u32 stride; |
| 113 | }; | 97 | |
| 114 | FrameBufferConfig top_framebuffer; | 98 | u32 address_right1; |
| 115 | FrameBufferConfig sub_framebuffer; | 99 | u32 address_right2; |
| 100 | } data; | ||
| 101 | }; | ||
| 102 | template<> | ||
| 103 | union Regs::Struct<Regs::FramebufferBottom> { | ||
| 104 | using Type = decltype(Regs::Struct<Regs::FramebufferTop>::data); | ||
| 105 | Type data; | ||
| 106 | }; | ||
| 107 | static_assert(sizeof(Regs::Struct<Regs::FramebufferTop>) == 0x40, "Structure size and register block length don't match"); | ||
| 108 | |||
| 109 | template<> | ||
| 110 | union Regs::Struct<Regs::DisplayTransfer> { | ||
| 111 | using Format = Regs::FramebufferFormat; | ||
| 116 | 112 | ||
| 117 | struct { | 113 | struct { |
| 118 | u32 input_address; | 114 | u32 input_address; |
| @@ -144,21 +140,31 @@ struct Registers { | |||
| 144 | u32 flags; | 140 | u32 flags; |
| 145 | 141 | ||
| 146 | BitField< 0, 1, u32> flip_data; | 142 | BitField< 0, 1, u32> flip_data; |
| 147 | BitField< 8, 3, FramebufferFormat> input_format; | 143 | BitField< 8, 3, Format> input_format; |
| 148 | BitField<12, 3, FramebufferFormat> output_format; | 144 | BitField<12, 3, Format> output_format; |
| 149 | BitField<16, 1, u32> output_tiled; | 145 | BitField<16, 1, u32> output_tiled; |
| 150 | }; | 146 | }; |
| 151 | 147 | ||
| 152 | u32 unknown; | 148 | u32 unknown; |
| 153 | u32 trigger; | 149 | u32 trigger; |
| 154 | } display_transfer; | 150 | } data; |
| 151 | }; | ||
| 152 | static_assert(sizeof(Regs::Struct<Regs::DisplayTransfer>) == 0x1C, "Structure size and register block length don't match"); | ||
| 155 | 153 | ||
| 156 | u32 command_list_size; | 154 | template<> |
| 157 | u32 command_list_address; | 155 | union Regs::Struct<Regs::CommandProcessor> { |
| 158 | u32 command_processing_enabled; | 156 | struct { |
| 157 | u32 size; | ||
| 158 | u32 pad0; | ||
| 159 | u32 address; | ||
| 160 | u32 pad1; | ||
| 161 | u32 trigger; | ||
| 162 | } data; | ||
| 159 | }; | 163 | }; |
| 164 | static_assert(sizeof(Regs::Struct<Regs::CommandProcessor>) == 0x14, "Structure size and register block length don't match"); | ||
| 165 | |||
| 160 | 166 | ||
| 161 | extern Registers g_regs; | 167 | extern RegisterSet<u32, Regs> g_regs; |
| 162 | 168 | ||
| 163 | enum { | 169 | enum { |
| 164 | TOP_ASPECT_X = 0x5, | 170 | TOP_ASPECT_X = 0x5, |
| @@ -208,7 +214,7 @@ enum FramebufferLocation { | |||
| 208 | 214 | ||
| 209 | /** | 215 | /** |
| 210 | * Sets whether the framebuffers are in the GSP heap (FCRAM) or VRAM | 216 | * Sets whether the framebuffers are in the GSP heap (FCRAM) or VRAM |
| 211 | * @param | 217 | * @param |
| 212 | */ | 218 | */ |
| 213 | void SetFramebufferLocation(const FramebufferLocation mode); | 219 | void SetFramebufferLocation(const FramebufferLocation mode); |
| 214 | 220 | ||