summaryrefslogtreecommitdiff
path: root/src/core/hle/service/gsp.cpp
diff options
context:
space:
mode:
authorGravatar Tony Wasserka2014-08-19 20:57:43 +0200
committerGravatar Tony Wasserka2014-08-25 22:03:18 +0200
commit14b24a75b37545faf49584864cb85555f22a0154 (patch)
treedf4350faa6f2856b876abe6707e856dfa2e10f83 /src/core/hle/service/gsp.cpp
parentGSP: Implement SetBufferSwap. (diff)
downloadyuzu-14b24a75b37545faf49584864cb85555f22a0154.tar.gz
yuzu-14b24a75b37545faf49584864cb85555f22a0154.tar.xz
yuzu-14b24a75b37545faf49584864cb85555f22a0154.zip
GSP: Update framebuffer information when necessary.
Diffstat (limited to 'src/core/hle/service/gsp.cpp')
-rw-r--r--src/core/hle/service/gsp.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/core/hle/service/gsp.cpp b/src/core/hle/service/gsp.cpp
index 417c01b83..027ba5a37 100644
--- a/src/core/hle/service/gsp.cpp
+++ b/src/core/hle/service/gsp.cpp
@@ -36,6 +36,17 @@ static inline u8* GetCommandBuffer(u32 thread_id) {
36 0x800 + (thread_id * sizeof(CommandBuffer))); 36 0x800 + (thread_id * sizeof(CommandBuffer)));
37} 37}
38 38
39static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) {
40 if (0 == g_shared_memory)
41 return nullptr;
42
43 _dbg_assert_msg_(GSP, screen_index < 2, "Invalid screen index");
44
45 // For each thread there are two FrameBufferUpdate fields
46 u32 offset = 0x200 + (2 * thread_id + screen_index) * sizeof(FrameBufferUpdate);
47 return (FrameBufferUpdate*)Kernel::GetSharedMemoryPointer(g_shared_memory, offset);
48}
49
39/// Gets a pointer to the interrupt relay queue for a given thread index 50/// Gets a pointer to the interrupt relay queue for a given thread index
40static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) { 51static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) {
41 return (InterruptRelayQueue*)Kernel::GetSharedMemoryPointer(g_shared_memory, 52 return (InterruptRelayQueue*)Kernel::GetSharedMemoryPointer(g_shared_memory,
@@ -166,6 +177,7 @@ void RegisterInterruptRelayQueue(Service::Interface* self) {
166/** 177/**
167 * Signals that the specified interrupt type has occurred to userland code 178 * Signals that the specified interrupt type has occurred to userland code
168 * @param interrupt_id ID of interrupt that is being signalled 179 * @param interrupt_id ID of interrupt that is being signalled
180 * @todo This should probably take a thread_id parameter and only signal this thread?
169 */ 181 */
170void SignalInterrupt(InterruptId interrupt_id) { 182void SignalInterrupt(InterruptId interrupt_id) {
171 if (0 == g_interrupt_event) { 183 if (0 == g_interrupt_event) {
@@ -191,7 +203,7 @@ void SignalInterrupt(InterruptId interrupt_id) {
191} 203}
192 204
193/// Executes the next GSP command 205/// Executes the next GSP command
194void ExecuteCommand(const Command& command) { 206void ExecuteCommand(const Command& command, u32 thread_id) {
195 // Utility function to convert register ID to address 207 // Utility function to convert register ID to address
196 auto WriteGPURegister = [](u32 id, u32 data) { 208 auto WriteGPURegister = [](u32 id, u32 data) {
197 GPU::Write<u32>(0x1EF00000 + 4 * id, data); 209 GPU::Write<u32>(0x1EF00000 + 4 * id, data);
@@ -262,6 +274,15 @@ void ExecuteCommand(const Command& command) {
262 SignalInterrupt(InterruptId::PPF); 274 SignalInterrupt(InterruptId::PPF);
263 SignalInterrupt(InterruptId::P3D); 275 SignalInterrupt(InterruptId::P3D);
264 SignalInterrupt(InterruptId::DMA); 276 SignalInterrupt(InterruptId::DMA);
277
278 // Update framebuffer information if requested
279 for (int screen_id = 0; screen_id < 2; ++screen_id) {
280 FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id);
281 if (info->is_dirty)
282 SetBufferSwap(screen_id, info->framebuffer_info[info->index]);
283
284 info->is_dirty = false;
285 }
265 break; 286 break;
266 } 287 }
267 288
@@ -304,7 +325,7 @@ void TriggerCmdReqQueue(Service::Interface* self) {
304 g_debugger.GXCommandProcessed((u8*)&command_buffer->commands[i]); 325 g_debugger.GXCommandProcessed((u8*)&command_buffer->commands[i]);
305 326
306 // Decode and execute command 327 // Decode and execute command
307 ExecuteCommand(command_buffer->commands[i]); 328 ExecuteCommand(command_buffer->commands[i], thread_id);
308 329
309 // Indicates that command has completed 330 // Indicates that command has completed
310 command_buffer->number_commands = command_buffer->number_commands - 1; 331 command_buffer->number_commands = command_buffer->number_commands - 1;