From 05a44ed353853a8b693cb5f627ca41c6c045791b Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 21 Dec 2017 11:43:30 -0500 Subject: [PATCH] HLE/GSP: Keep track of the thread that currently has the GPU right. This thread is the only one for which the GSP interrupts should be signaled, except for the PDC0/1 interrupts. --- src/core/hle/service/gsp/gsp_gpu.cpp | 20 ++++++++++++-------- src/core/hle/service/gsp/gsp_gpu.h | 4 +++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/core/hle/service/gsp/gsp_gpu.cpp b/src/core/hle/service/gsp/gsp_gpu.cpp index 4e854164e..15e8de322 100644 --- a/src/core/hle/service/gsp/gsp_gpu.cpp +++ b/src/core/hle/service/gsp/gsp_gpu.cpp @@ -370,9 +370,6 @@ void GSP_GPU::UnregisterInterruptRelayQueue(Kernel::HLERequestContext& ctx) { * @todo This probably does not belong in the GSP module, instead move to video_core */ void GSP_GPU::SignalInterrupt(InterruptId interrupt_id) { - if (!gpu_right_acquired) { - return; - } if (nullptr == shared_memory) { LOG_WARNING(Service_GSP, "cannot synchronize until GSP shared memory has been created!"); return; @@ -634,18 +631,26 @@ void GSP_GPU::AcquireRight(Kernel::HLERequestContext& ctx) { u32 flag = rp.Pop(); auto process = rp.PopObject(); - gpu_right_acquired = true; + // TODO(Subv): This case should put the caller thread to sleep until the right is released. + ASSERT_MSG(active_thread_id == -1, "GPU right has already been acquired"); + + SessionData* session_data = GetSessionData(ctx.Session()); + active_thread_id = session_data->thread_id; IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_GSP, "called flag=%08X process=%u", flag, process->process_id); + LOG_WARNING(Service_GSP, "called flag=%08X process=%u thread_id=%u", flag, process->process_id, + active_thread_id); } void GSP_GPU::ReleaseRight(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x17, 0, 0); - gpu_right_acquired = false; + SessionData* session_data = GetSessionData(ctx.Session()); + ASSERT_MSG(active_thread_id == session_data->thread_id, + "Wrong thread tried to release GPU right"); + active_thread_id = -1; IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); @@ -669,7 +674,7 @@ void GSP_GPU::StoreDataCache(Kernel::HLERequestContext& ctx) { SessionData* GSP_GPU::FindRegisteredThreadData(u32 thread_id) { for (auto& session_info : connected_sessions) { - SessionData* data = static_cast(session_info.data.get()) + SessionData* data = static_cast(session_info.data.get()); if (!data->registered) continue; if (data->thread_id == thread_id) @@ -719,7 +724,6 @@ GSP_GPU::GSP_GPU() : ServiceFramework("gsp::Gpu", 2) { MemoryPermission::ReadWrite, 0, Kernel::MemoryRegion::BASE, "GSP:SharedMemory"); - gpu_right_acquired = false; first_initialization = true; }; } // namespace GSP diff --git a/src/core/hle/service/gsp/gsp_gpu.h b/src/core/hle/service/gsp/gsp_gpu.h index 737525653..01bab8652 100644 --- a/src/core/hle/service/gsp/gsp_gpu.h +++ b/src/core/hle/service/gsp/gsp_gpu.h @@ -369,7 +369,9 @@ private: /// GSP shared memory Kernel::SharedPtr shared_memory; - bool gpu_right_acquired = false; + /// Thread id that currently has GPU rights or -1 if none. + int active_thread_id = -1; + bool first_initialization = true; };