summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Tony Wasserka2014-07-11 19:10:08 +0200
committerGravatar Tony Wasserka2014-07-23 00:33:08 +0200
commit0b4055c1520fbe7f697d2f1f93a85b559504cca4 (patch)
treeee387998414415a41a83628ab9d61772a2c494aa /src
parentGPU: Properly implement display transfers. (diff)
downloadyuzu-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.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 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) {
84template <typename T> 84template <typename T>
85inline void Read(T &var, const u32 addr) { 85inline 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) {
154template <typename T> 194template <typename T>
155inline void Write(u32 addr, const T data) { 195inline 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
15struct Registers { 15struct 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