diff options
| author | 2014-07-11 19:10:08 +0200 | |
|---|---|---|
| committer | 2014-07-23 00:33:08 +0200 | |
| commit | 0b4055c1520fbe7f697d2f1f93a85b559504cca4 (patch) | |
| tree | ee387998414415a41a83628ab9d61772a2c494aa /src | |
| parent | GPU: Properly implement display transfers. (diff) | |
| download | yuzu-0b4055c1520fbe7f697d2f1f93a85b559504cca4.tar.gz yuzu-0b4055c1520fbe7f697d2f1f93a85b559504cca4.tar.xz yuzu-0b4055c1520fbe7f697d2f1f93a85b559504cca4.zip | |
GPU: Add proper framebuffer register handling.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hw/gpu.cpp | 53 | ||||
| -rw-r--r-- | src/core/hw/gpu.h | 63 |
2 files changed, 105 insertions, 11 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index e05e1b023..fad3439c8 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp | |||
| @@ -84,6 +84,10 @@ const u8* GetFramebufferPointer(const u32 address) { | |||
| 84 | template <typename T> | 84 | template <typename T> |
| 85 | inline void Read(T &var, const u32 addr) { | 85 | inline void Read(T &var, const u32 addr) { |
| 86 | switch (addr) { | 86 | switch (addr) { |
| 87 | case Registers::FramebufferTopSize: | ||
| 88 | var = g_regs.top_framebuffer.size; | ||
| 89 | break; | ||
| 90 | |||
| 87 | case Registers::FramebufferTopLeft1: | 91 | case Registers::FramebufferTopLeft1: |
| 88 | var = g_regs.framebuffer_top_left_1; | 92 | var = g_regs.framebuffer_top_left_1; |
| 89 | break; | 93 | break; |
| @@ -92,6 +96,18 @@ inline void Read(T &var, const u32 addr) { | |||
| 92 | var = g_regs.framebuffer_top_left_2; | 96 | var = g_regs.framebuffer_top_left_2; |
| 93 | break; | 97 | break; |
| 94 | 98 | ||
| 99 | case Registers::FramebufferTopFormat: | ||
| 100 | var = g_regs.top_framebuffer.format; | ||
| 101 | break; | ||
| 102 | |||
| 103 | case Registers::FramebufferTopSwapBuffers: | ||
| 104 | var = g_regs.top_framebuffer.active_fb; | ||
| 105 | break; | ||
| 106 | |||
| 107 | case Registers::FramebufferTopStride: | ||
| 108 | var = g_regs.top_framebuffer.stride; | ||
| 109 | break; | ||
| 110 | |||
| 95 | case Registers::FramebufferTopRight1: | 111 | case Registers::FramebufferTopRight1: |
| 96 | var = g_regs.framebuffer_top_right_1; | 112 | var = g_regs.framebuffer_top_right_1; |
| 97 | break; | 113 | break; |
| @@ -100,6 +116,10 @@ inline void Read(T &var, const u32 addr) { | |||
| 100 | var = g_regs.framebuffer_top_right_2; | 116 | var = g_regs.framebuffer_top_right_2; |
| 101 | break; | 117 | break; |
| 102 | 118 | ||
| 119 | case Registers::FramebufferSubSize: | ||
| 120 | var = g_regs.sub_framebuffer.size; | ||
| 121 | break; | ||
| 122 | |||
| 103 | case Registers::FramebufferSubLeft1: | 123 | case Registers::FramebufferSubLeft1: |
| 104 | var = g_regs.framebuffer_sub_left_1; | 124 | var = g_regs.framebuffer_sub_left_1; |
| 105 | break; | 125 | break; |
| @@ -108,6 +128,26 @@ inline void Read(T &var, const u32 addr) { | |||
| 108 | var = g_regs.framebuffer_sub_right_1; | 128 | var = g_regs.framebuffer_sub_right_1; |
| 109 | break; | 129 | break; |
| 110 | 130 | ||
| 131 | case Registers::FramebufferSubFormat: | ||
| 132 | var = g_regs.sub_framebuffer.format; | ||
| 133 | break; | ||
| 134 | |||
| 135 | case Registers::FramebufferSubSwapBuffers: | ||
| 136 | var = g_regs.sub_framebuffer.active_fb; | ||
| 137 | break; | ||
| 138 | |||
| 139 | case Registers::FramebufferSubStride: | ||
| 140 | var = g_regs.sub_framebuffer.stride; | ||
| 141 | break; | ||
| 142 | |||
| 143 | case Registers::FramebufferSubLeft2: | ||
| 144 | var = g_regs.framebuffer_sub_left_2; | ||
| 145 | break; | ||
| 146 | |||
| 147 | case Registers::FramebufferSubRight2: | ||
| 148 | var = g_regs.framebuffer_sub_right_2; | ||
| 149 | break; | ||
| 150 | |||
| 111 | case Registers::DisplayInputBufferAddr: | 151 | case Registers::DisplayInputBufferAddr: |
| 112 | var = g_regs.display_transfer.input_address; | 152 | var = g_regs.display_transfer.input_address; |
| 113 | break; | 153 | break; |
| @@ -154,6 +194,17 @@ inline void Read(T &var, const u32 addr) { | |||
| 154 | template <typename T> | 194 | template <typename T> |
| 155 | inline void Write(u32 addr, const T data) { | 195 | inline void Write(u32 addr, const T data) { |
| 156 | switch (static_cast<Registers::Id>(addr)) { | 196 | switch (static_cast<Registers::Id>(addr)) { |
| 197 | // TODO: Framebuffer registers!! | ||
| 198 | case Registers::FramebufferTopSwapBuffers: | ||
| 199 | g_regs.top_framebuffer.active_fb = data; | ||
| 200 | // TODO: Not sure if this should only be done upon a change! | ||
| 201 | break; | ||
| 202 | |||
| 203 | case Registers::FramebufferSubSwapBuffers: | ||
| 204 | g_regs.sub_framebuffer.active_fb = data; | ||
| 205 | // TODO: Not sure if this should only be done upon a change! | ||
| 206 | break; | ||
| 207 | |||
| 157 | case Registers::DisplayInputBufferAddr: | 208 | case Registers::DisplayInputBufferAddr: |
| 158 | g_regs.display_transfer.input_address = data; | 209 | g_regs.display_transfer.input_address = data; |
| 159 | break; | 210 | break; |
| @@ -195,7 +246,7 @@ inline void Write(u32 addr, const T data) { | |||
| 195 | g_regs.display_transfer.output_height * g_regs.display_transfer.output_width * 4, | 246 | g_regs.display_transfer.output_height * g_regs.display_transfer.output_width * 4, |
| 196 | g_regs.display_transfer.GetPhysicalInputAddress(), (int)g_regs.display_transfer.input_width, (int)g_regs.display_transfer.input_height, | 247 | g_regs.display_transfer.GetPhysicalInputAddress(), (int)g_regs.display_transfer.input_width, (int)g_regs.display_transfer.input_height, |
| 197 | g_regs.display_transfer.GetPhysicalOutputAddress(), (int)g_regs.display_transfer.output_width, (int)g_regs.display_transfer.output_height, | 248 | g_regs.display_transfer.GetPhysicalOutputAddress(), (int)g_regs.display_transfer.output_width, (int)g_regs.display_transfer.output_height, |
| 198 | (int)g_regs.display_transfer.output_format); | 249 | (int)g_regs.display_transfer.output_format.Value()); |
| 199 | } | 250 | } |
| 200 | break; | 251 | break; |
| 201 | 252 | ||
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index 29eb7ed81..50c360814 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 | |||
| 14 | 14 | ||
| 15 | struct Registers { | 15 | struct Registers { |
| 16 | enum Id : u32 { | 16 | enum Id : u32 { |
| 17 | FramebufferTopLeft1 = 0x1EF00468, // Main LCD, first framebuffer for 3D left | 17 | FramebufferTopSize = 0x1EF0045C, |
| 18 | FramebufferTopLeft2 = 0x1EF0046C, // Main LCD, second framebuffer for 3D left | 18 | FramebufferTopLeft1 = 0x1EF00468, // Main LCD, first framebuffer for 3D left |
| 19 | FramebufferTopRight1 = 0x1EF00494, // Main LCD, first framebuffer for 3D right | 19 | FramebufferTopLeft2 = 0x1EF0046C, // Main LCD, second framebuffer for 3D left |
| 20 | FramebufferTopRight2 = 0x1EF00498, // Main LCD, second framebuffer for 3D right | 20 | FramebufferTopFormat = 0x1EF00470, |
| 21 | FramebufferSubLeft1 = 0x1EF00568, // Sub LCD, first framebuffer | 21 | FramebufferTopSwapBuffers = 0x1EF00478, |
| 22 | FramebufferSubLeft2 = 0x1EF0056C, // Sub LCD, second framebuffer | 22 | FramebufferTopStride = 0x1EF00490, // framebuffer row stride? |
| 23 | FramebufferSubRight1 = 0x1EF00594, // Sub LCD, unused first framebuffer | 23 | FramebufferTopRight1 = 0x1EF00494, // Main LCD, first framebuffer for 3D right |
| 24 | FramebufferSubRight2 = 0x1EF00598, // Sub LCD, unused second framebuffer | 24 | FramebufferTopRight2 = 0x1EF00498, // Main LCD, second framebuffer for 3D right |
| 25 | |||
| 26 | FramebufferSubSize = 0x1EF0055C, | ||
| 27 | FramebufferSubLeft1 = 0x1EF00568, // Sub LCD, first framebuffer | ||
| 28 | FramebufferSubLeft2 = 0x1EF0056C, // Sub LCD, second framebuffer | ||
| 29 | FramebufferSubFormat = 0x1EF00570, | ||
| 30 | FramebufferSubSwapBuffers = 0x1EF00578, | ||
| 31 | FramebufferSubStride = 0x1EF00590, // framebuffer row stride? | ||
| 32 | FramebufferSubRight1 = 0x1EF00594, // Sub LCD, unused first framebuffer | ||
| 33 | FramebufferSubRight2 = 0x1EF00598, // Sub LCD, unused second framebuffer | ||
| 25 | 34 | ||
| 26 | DisplayInputBufferAddr = 0x1EF00C00, | 35 | DisplayInputBufferAddr = 0x1EF00C00, |
| 27 | DisplayOutputBufferAddr = 0x1EF00C04, | 36 | DisplayOutputBufferAddr = 0x1EF00C04, |
| @@ -36,6 +45,15 @@ struct Registers { | |||
| 36 | ProcessCommandList = 0x1EF018F0, | 45 | ProcessCommandList = 0x1EF018F0, |
| 37 | }; | 46 | }; |
| 38 | 47 | ||
| 48 | enum class FramebufferFormat : u32 { | ||
| 49 | RGBA8 = 0, | ||
| 50 | RGB8 = 1, | ||
| 51 | RGB565 = 2, | ||
| 52 | RGB5A1 = 3, | ||
| 53 | RGBA4 = 4, | ||
| 54 | }; | ||
| 55 | |||
| 56 | // TODO: Move these into the framebuffer struct | ||
| 39 | u32 framebuffer_top_left_1; | 57 | u32 framebuffer_top_left_1; |
| 40 | u32 framebuffer_top_left_2; | 58 | u32 framebuffer_top_left_2; |
| 41 | u32 framebuffer_top_right_1; | 59 | u32 framebuffer_top_right_1; |
| @@ -45,6 +63,31 @@ struct Registers { | |||
| 45 | u32 framebuffer_sub_right_1; | 63 | u32 framebuffer_sub_right_1; |
| 46 | u32 framebuffer_sub_right_2; | 64 | u32 framebuffer_sub_right_2; |
| 47 | 65 | ||
| 66 | struct FrameBufferConfig { | ||
| 67 | union { | ||
| 68 | u32 size; | ||
| 69 | |||
| 70 | BitField< 0, 16, u32> width; | ||
| 71 | BitField<16, 16, u32> height; | ||
| 72 | }; | ||
| 73 | |||
| 74 | union { | ||
| 75 | u32 format; | ||
| 76 | |||
| 77 | BitField< 0, 3, FramebufferFormat> color_format; | ||
| 78 | }; | ||
| 79 | |||
| 80 | union { | ||
| 81 | u32 active_fb; | ||
| 82 | |||
| 83 | BitField<0, 1, u32> second_fb_active; | ||
| 84 | }; | ||
| 85 | |||
| 86 | u32 stride; | ||
| 87 | }; | ||
| 88 | FrameBufferConfig top_framebuffer; | ||
| 89 | FrameBufferConfig sub_framebuffer; | ||
| 90 | |||
| 48 | struct { | 91 | struct { |
| 49 | u32 input_address; | 92 | u32 input_address; |
| 50 | u32 output_address; | 93 | u32 output_address; |
| @@ -75,8 +118,8 @@ struct Registers { | |||
| 75 | u32 flags; | 118 | u32 flags; |
| 76 | 119 | ||
| 77 | BitField< 0, 1, u32> flip_data; | 120 | BitField< 0, 1, u32> flip_data; |
| 78 | BitField< 8, 3, u32> input_format; | 121 | BitField< 8, 3, FramebufferFormat> input_format; |
| 79 | BitField<12, 3, u32> output_format; | 122 | BitField<12, 3, FramebufferFormat> output_format; |
| 80 | BitField<16, 1, u32> output_tiled; | 123 | BitField<16, 1, u32> output_tiled; |
| 81 | }; | 124 | }; |
| 82 | 125 | ||