diff options
| author | 2014-07-25 11:23:28 +0200 | |
|---|---|---|
| committer | 2014-08-25 22:03:18 +0200 | |
| commit | 590c206ac8836f0e4544d2cb84191d77d07b9f36 (patch) | |
| tree | c6fe97637f83094e93ca74225f52dd655ab393fd /src/core | |
| parent | GSP: Add a helper function for convenience. (diff) | |
| download | yuzu-590c206ac8836f0e4544d2cb84191d77d07b9f36.tar.gz yuzu-590c206ac8836f0e4544d2cb84191d77d07b9f36.tar.xz yuzu-590c206ac8836f0e4544d2cb84191d77d07b9f36.zip | |
GSP: Implement SetBufferSwap.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/gsp.cpp | 36 | ||||
| -rw-r--r-- | src/core/hle/service/gsp.h | 12 |
2 files changed, 47 insertions, 1 deletions
diff --git a/src/core/hle/service/gsp.cpp b/src/core/hle/service/gsp.cpp index f793b592c..417c01b83 100644 --- a/src/core/hle/service/gsp.cpp +++ b/src/core/hle/service/gsp.cpp | |||
| @@ -105,6 +105,40 @@ void ReadHWRegs(Service::Interface* self) { | |||
| 105 | } | 105 | } |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) { | ||
| 109 | u32 base_address = 0x400000; | ||
| 110 | if (info.active_fb == 0) { | ||
| 111 | WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].address_left1), 4, &info.address_left); | ||
| 112 | WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].address_right1), 4, &info.address_right); | ||
| 113 | } else { | ||
| 114 | WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].address_left2), 4, &info.address_left); | ||
| 115 | WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].address_right2), 4, &info.address_right); | ||
| 116 | } | ||
| 117 | WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].stride), 4, &info.stride); | ||
| 118 | WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].color_format), 4, &info.format); | ||
| 119 | WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].active_fb), 4, &info.shown_fb); | ||
| 120 | } | ||
| 121 | |||
| 122 | /** | ||
| 123 | * GSP_GPU::SetBufferSwap service function | ||
| 124 | * | ||
| 125 | * Updates GPU display framebuffer configuration using the specified parameters. | ||
| 126 | * | ||
| 127 | * Inputs: | ||
| 128 | * 1 : Screen ID (0 = top screen, 1 = bottom screen) | ||
| 129 | * 2-7 : FrameBufferInfo structure | ||
| 130 | * Outputs: | ||
| 131 | * 1: Result code | ||
| 132 | */ | ||
| 133 | void SetBufferSwap(Service::Interface* self) { | ||
| 134 | u32* cmd_buff = Service::GetCommandBuffer(); | ||
| 135 | u32 screen_id = cmd_buff[1]; | ||
| 136 | FrameBufferInfo* fb_info = (FrameBufferInfo*)&cmd_buff[2]; | ||
| 137 | SetBufferSwap(screen_id, *fb_info); | ||
| 138 | |||
| 139 | cmd_buff[1] = 0; // No error | ||
| 140 | } | ||
| 141 | |||
| 108 | /** | 142 | /** |
| 109 | * GSP_GPU::RegisterInterruptRelayQueue service function | 143 | * GSP_GPU::RegisterInterruptRelayQueue service function |
| 110 | * Inputs: | 144 | * Inputs: |
| @@ -283,7 +317,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 283 | {0x00020084, nullptr, "WriteHWRegsWithMask"}, | 317 | {0x00020084, nullptr, "WriteHWRegsWithMask"}, |
| 284 | {0x00030082, nullptr, "WriteHWRegRepeat"}, | 318 | {0x00030082, nullptr, "WriteHWRegRepeat"}, |
| 285 | {0x00040080, ReadHWRegs, "ReadHWRegs"}, | 319 | {0x00040080, ReadHWRegs, "ReadHWRegs"}, |
| 286 | {0x00050200, nullptr, "SetBufferSwap"}, | 320 | {0x00050200, SetBufferSwap, "SetBufferSwap"}, |
| 287 | {0x00060082, nullptr, "SetCommandList"}, | 321 | {0x00060082, nullptr, "SetCommandList"}, |
| 288 | {0x000700C2, nullptr, "RequestDma"}, | 322 | {0x000700C2, nullptr, "RequestDma"}, |
| 289 | {0x00080082, nullptr, "FlushDataCache"}, | 323 | {0x00080082, nullptr, "FlushDataCache"}, |
diff --git a/src/core/hle/service/gsp.h b/src/core/hle/service/gsp.h index b25dbb7bc..884cfd65a 100644 --- a/src/core/hle/service/gsp.h +++ b/src/core/hle/service/gsp.h | |||
| @@ -64,6 +64,18 @@ struct InterruptRelayQueue { | |||
| 64 | static_assert(sizeof(InterruptRelayQueue) == 0x40, | 64 | static_assert(sizeof(InterruptRelayQueue) == 0x40, |
| 65 | "InterruptRelayQueue struct has incorrect size"); | 65 | "InterruptRelayQueue struct has incorrect size"); |
| 66 | 66 | ||
| 67 | struct FrameBufferInfo { | ||
| 68 | BitField<0, 1, u32> active_fb; // 0 = first, 1 = second | ||
| 69 | |||
| 70 | u32 address_left; | ||
| 71 | u32 address_right; | ||
| 72 | u32 stride; // maps to 0x1EF00X90 ? | ||
| 73 | u32 format; // maps to 0x1EF00X70 ? | ||
| 74 | u32 shown_fb; // maps to 0x1EF00X78 ? | ||
| 75 | u32 unknown; | ||
| 76 | }; | ||
| 77 | static_assert(sizeof(FrameBufferInfo) == 0x1c, "Struct has incorrect size"); | ||
| 78 | |||
| 67 | /// GSP command | 79 | /// GSP command |
| 68 | struct Command { | 80 | struct Command { |
| 69 | BitField<0, 8, CommandId> id; | 81 | BitField<0, 8, CommandId> id; |