diff options
| author | 2018-01-16 21:06:52 -0500 | |
|---|---|---|
| committer | 2018-01-16 21:06:52 -0500 | |
| commit | 8c05e935bd14ab526e35a33b854e36b30aacdcc0 (patch) | |
| tree | fd6d1db6ea25ee744f4e65733b4450bdd0fab5ac /src/core | |
| parent | Merge pull request #52 from ogniK5377/fsp (diff) | |
| parent | applet_oe: Fix GetOperationMode and GetPerformanceMode. (diff) | |
| download | yuzu-8c05e935bd14ab526e35a33b854e36b30aacdcc0.tar.gz yuzu-8c05e935bd14ab526e35a33b854e36b30aacdcc0.tar.xz yuzu-8c05e935bd14ab526e35a33b854e36b30aacdcc0.zip | |
Merge pull request #55 from bunnei/subv-improvements
Improvements to IPC, AppletOE, APM, VI, SVC
Diffstat (limited to 'src/core')
23 files changed, 381 insertions, 216 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f5c92a5aa..2eab81ad6 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -48,8 +48,8 @@ set(SRCS | |||
| 48 | hle/service/nvdrv/devices/nvdisp_disp0.cpp | 48 | hle/service/nvdrv/devices/nvdisp_disp0.cpp |
| 49 | hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 49 | hle/service/nvdrv/devices/nvhost_as_gpu.cpp |
| 50 | hle/service/nvdrv/devices/nvmap.cpp | 50 | hle/service/nvdrv/devices/nvmap.cpp |
| 51 | hle/service/nvdrv/interface.cpp | ||
| 51 | hle/service/nvdrv/nvdrv.cpp | 52 | hle/service/nvdrv/nvdrv.cpp |
| 52 | hle/service/nvdrv/nvdrv_a.cpp | ||
| 53 | hle/service/pctl/pctl.cpp | 53 | hle/service/pctl/pctl.cpp |
| 54 | hle/service/pctl/pctl_a.cpp | 54 | hle/service/pctl/pctl_a.cpp |
| 55 | hle/service/service.cpp | 55 | hle/service/service.cpp |
| @@ -136,8 +136,8 @@ set(HEADERS | |||
| 136 | hle/service/nvdrv/devices/nvdisp_disp0.h | 136 | hle/service/nvdrv/devices/nvdisp_disp0.h |
| 137 | hle/service/nvdrv/devices/nvhost_as_gpu.h | 137 | hle/service/nvdrv/devices/nvhost_as_gpu.h |
| 138 | hle/service/nvdrv/devices/nvmap.h | 138 | hle/service/nvdrv/devices/nvmap.h |
| 139 | hle/service/nvdrv/interface.h | ||
| 139 | hle/service/nvdrv/nvdrv.h | 140 | hle/service/nvdrv/nvdrv.h |
| 140 | hle/service/nvdrv/nvdrv_a.h | ||
| 141 | hle/service/pctl/pctl.h | 141 | hle/service/pctl/pctl.h |
| 142 | hle/service/pctl/pctl_a.h | 142 | hle/service/pctl/pctl_a.h |
| 143 | hle/service/service.h | 143 | hle/service/service.h |
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 0f1077d9e..25530a3c8 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h | |||
| @@ -9,10 +9,13 @@ | |||
| 9 | #include <type_traits> | 9 | #include <type_traits> |
| 10 | #include <utility> | 10 | #include <utility> |
| 11 | #include "core/hle/ipc.h" | 11 | #include "core/hle/ipc.h" |
| 12 | #include "core/hle/kernel/client_port.h" | ||
| 13 | #include "core/hle/kernel/client_session.h" | ||
| 12 | #include "core/hle/kernel/domain.h" | 14 | #include "core/hle/kernel/domain.h" |
| 13 | #include "core/hle/kernel/handle_table.h" | 15 | #include "core/hle/kernel/handle_table.h" |
| 14 | #include "core/hle/kernel/hle_ipc.h" | 16 | #include "core/hle/kernel/hle_ipc.h" |
| 15 | #include "core/hle/kernel/kernel.h" | 17 | #include "core/hle/kernel/kernel.h" |
| 18 | #include "core/hle/kernel/server_port.h" | ||
| 16 | 19 | ||
| 17 | namespace IPC { | 20 | namespace IPC { |
| 18 | 21 | ||
| @@ -63,13 +66,20 @@ public: | |||
| 63 | : RequestHelperBase(context) { | 66 | : RequestHelperBase(context) { |
| 64 | memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH); | 67 | memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH); |
| 65 | 68 | ||
| 69 | context.ClearIncomingObjects(); | ||
| 70 | |||
| 66 | IPC::CommandHeader header{}; | 71 | IPC::CommandHeader header{}; |
| 67 | 72 | ||
| 68 | // The entire size of the raw data section in u32 units, including the 16 bytes of mandatory | 73 | // The entire size of the raw data section in u32 units, including the 16 bytes of mandatory |
| 69 | // padding. | 74 | // padding. |
| 70 | u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size; | 75 | u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size; |
| 71 | if (context.IsDomain()) | 76 | if (context.IsDomain()) { |
| 72 | raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects; | 77 | raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects; |
| 78 | } else { | ||
| 79 | // If we're not in a domain, turn the domain object parameters into move handles. | ||
| 80 | num_handles_to_move += num_domain_objects; | ||
| 81 | num_domain_objects = 0; | ||
| 82 | } | ||
| 73 | 83 | ||
| 74 | header.data_size.Assign(raw_data_size); | 84 | header.data_size.Assign(raw_data_size); |
| 75 | if (num_handles_to_copy || num_handles_to_move) { | 85 | if (num_handles_to_copy || num_handles_to_move) { |
| @@ -100,7 +110,15 @@ public: | |||
| 100 | 110 | ||
| 101 | template <class T, class... Args> | 111 | template <class T, class... Args> |
| 102 | void PushIpcInterface(Args&&... args) { | 112 | void PushIpcInterface(Args&&... args) { |
| 103 | context->AddDomainObject(std::make_shared<T>(std::forward<Args>(args)...)); | 113 | auto iface = std::make_shared<T>(std::forward<Args>(args)...); |
| 114 | if (context->IsDomain()) { | ||
| 115 | context->AddDomainObject(std::move(iface)); | ||
| 116 | } else { | ||
| 117 | auto port = iface->CreatePort(); | ||
| 118 | auto session = port->Connect(); | ||
| 119 | ASSERT(session.Succeeded()); | ||
| 120 | context->AddMoveObject(std::move(session).Unwrap()); | ||
| 121 | } | ||
| 104 | } | 122 | } |
| 105 | 123 | ||
| 106 | // Validate on destruction, as there shouldn't be any case where we don't want it | 124 | // Validate on destruction, as there shouldn't be any case where we don't want it |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 164c6db69..6dceb766d 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -175,6 +175,14 @@ public: | |||
| 175 | domain_objects.emplace_back(std::move(object)); | 175 | domain_objects.emplace_back(std::move(object)); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | /// Clears the list of objects so that no lingering objects are written accidentally to the | ||
| 179 | /// response buffer. | ||
| 180 | void ClearIncomingObjects() { | ||
| 181 | move_objects.clear(); | ||
| 182 | copy_objects.clear(); | ||
| 183 | domain_objects.clear(); | ||
| 184 | } | ||
| 185 | |||
| 178 | private: | 186 | private: |
| 179 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; | 187 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; |
| 180 | SharedPtr<Kernel::Domain> domain; | 188 | SharedPtr<Kernel::Domain> domain; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 056ba28ef..088058ebc 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -255,8 +255,9 @@ static ResultCode CancelSynchronization(Handle thread_handle) { | |||
| 255 | /// Attempts to locks a mutex, creating it if it does not already exist | 255 | /// Attempts to locks a mutex, creating it if it does not already exist |
| 256 | static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr, | 256 | static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr, |
| 257 | Handle requesting_thread_handle) { | 257 | Handle requesting_thread_handle) { |
| 258 | LOG_TRACE(Kernel_SVC, "called holding_thread_handle=0x%08X, mutex_addr=0x%llx, " | 258 | LOG_TRACE(Kernel_SVC, |
| 259 | "requesting_current_thread_handle=0x%08X", | 259 | "called holding_thread_handle=0x%08X, mutex_addr=0x%llx, " |
| 260 | "requesting_current_thread_handle=0x%08X", | ||
| 260 | holding_thread_handle, mutex_addr, requesting_thread_handle); | 261 | holding_thread_handle, mutex_addr, requesting_thread_handle); |
| 261 | 262 | ||
| 262 | SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle); | 263 | SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle); |
| @@ -304,8 +305,6 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 304 | LOG_TRACE(Kernel_SVC, "called info_id=0x%X, info_sub_id=0x%X, handle=0x%08X", info_id, | 305 | LOG_TRACE(Kernel_SVC, "called info_id=0x%X, info_sub_id=0x%X, handle=0x%08X", info_id, |
| 305 | info_sub_id, handle); | 306 | info_sub_id, handle); |
| 306 | 307 | ||
| 307 | ASSERT(handle == 0 || handle == CurrentProcess); | ||
| 308 | |||
| 309 | auto& vm_manager = g_current_process->vm_manager; | 308 | auto& vm_manager = g_current_process->vm_manager; |
| 310 | 309 | ||
| 311 | switch (static_cast<GetInfoType>(info_id)) { | 310 | switch (static_cast<GetInfoType>(info_id)) { |
| @@ -321,6 +320,12 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 321 | case GetInfoType::MapRegionSize: | 320 | case GetInfoType::MapRegionSize: |
| 322 | *result = vm_manager.GetAddressSpaceSize(); | 321 | *result = vm_manager.GetAddressSpaceSize(); |
| 323 | break; | 322 | break; |
| 323 | case GetInfoType::HeapRegionBaseAddr: | ||
| 324 | *result = vm_manager.GetNewMapRegionBaseAddr() + vm_manager.GetNewMapRegionSize(); | ||
| 325 | break; | ||
| 326 | case GetInfoType::HeapRegionSize: | ||
| 327 | *result = Memory::HEAP_SIZE; | ||
| 328 | break; | ||
| 324 | case GetInfoType::TotalMemoryUsage: | 329 | case GetInfoType::TotalMemoryUsage: |
| 325 | *result = vm_manager.GetTotalMemoryUsage(); | 330 | *result = vm_manager.GetTotalMemoryUsage(); |
| 326 | break; | 331 | break; |
| @@ -345,6 +350,15 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 345 | case GetInfoType::IsVirtualAddressMemoryEnabled: | 350 | case GetInfoType::IsVirtualAddressMemoryEnabled: |
| 346 | *result = g_current_process->is_virtual_address_memory_enabled; | 351 | *result = g_current_process->is_virtual_address_memory_enabled; |
| 347 | break; | 352 | break; |
| 353 | case GetInfoType::TitleId: | ||
| 354 | LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0"); | ||
| 355 | *result = 0; | ||
| 356 | break; | ||
| 357 | case GetInfoType::PrivilegedProcessId: | ||
| 358 | LOG_WARNING(Kernel_SVC, | ||
| 359 | "(STUBBED) Attempted to query priviledged process id bounds, returned 0"); | ||
| 360 | *result = 0; | ||
| 361 | break; | ||
| 348 | default: | 362 | default: |
| 349 | UNIMPLEMENTED(); | 363 | UNIMPLEMENTED(); |
| 350 | } | 364 | } |
| @@ -533,8 +547,9 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V | |||
| 533 | 547 | ||
| 534 | Core::System::GetInstance().PrepareReschedule(); | 548 | Core::System::GetInstance().PrepareReschedule(); |
| 535 | 549 | ||
| 536 | LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " | 550 | LOG_TRACE(Kernel_SVC, |
| 537 | "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", | 551 | "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " |
| 552 | "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", | ||
| 538 | entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle); | 553 | entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle); |
| 539 | 554 | ||
| 540 | return RESULT_SUCCESS; | 555 | return RESULT_SUCCESS; |
diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h index a56fd3602..42cc41da3 100644 --- a/src/core/hle/kernel/svc.h +++ b/src/core/hle/kernel/svc.h | |||
| @@ -44,6 +44,7 @@ enum class GetInfoType : u64 { | |||
| 44 | // 3.0.0+ | 44 | // 3.0.0+ |
| 45 | IsVirtualAddressMemoryEnabled = 16, | 45 | IsVirtualAddressMemoryEnabled = 16, |
| 46 | TitleId = 18, | 46 | TitleId = 18, |
| 47 | // 4.0.0+ | ||
| 47 | PrivilegedProcessId = 19, | 48 | PrivilegedProcessId = 19, |
| 48 | }; | 49 | }; |
| 49 | 50 | ||
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index b629ac509..b360e7e5f 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include "core/hle/ipc_helpers.h" | 6 | #include "core/hle/ipc_helpers.h" |
| 7 | #include "core/hle/kernel/event.h" | 7 | #include "core/hle/kernel/event.h" |
| 8 | #include "core/hle/service/am/applet_oe.h" | 8 | #include "core/hle/service/am/applet_oe.h" |
| 9 | #include "core/hle/service/apm/apm.h" | ||
| 9 | 10 | ||
| 10 | namespace Service { | 11 | namespace Service { |
| 11 | namespace AM { | 12 | namespace AM { |
| @@ -71,6 +72,15 @@ private: | |||
| 71 | // Takes 3 input u8s with each field located immediately after the previous u8, these are | 72 | // Takes 3 input u8s with each field located immediately after the previous u8, these are |
| 72 | // bool flags. No output. | 73 | // bool flags. No output. |
| 73 | 74 | ||
| 75 | IPC::RequestParser rp{ctx}; | ||
| 76 | |||
| 77 | struct FocusHandlingModeParams { | ||
| 78 | u8 unknown0; | ||
| 79 | u8 unknown1; | ||
| 80 | u8 unknown2; | ||
| 81 | }; | ||
| 82 | auto flags = rp.PopRaw<FocusHandlingModeParams>(); | ||
| 83 | |||
| 74 | IPC::RequestBuilder rb{ctx, 2}; | 84 | IPC::RequestBuilder rb{ctx, 2}; |
| 75 | rb.Push(RESULT_SUCCESS); | 85 | rb.Push(RESULT_SUCCESS); |
| 76 | 86 | ||
| @@ -85,27 +95,38 @@ private: | |||
| 85 | } | 95 | } |
| 86 | 96 | ||
| 87 | void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) { | 97 | void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) { |
| 98 | IPC::RequestParser rp{ctx}; | ||
| 99 | |||
| 100 | bool flag = rp.Pop<bool>(); | ||
| 101 | |||
| 88 | IPC::RequestBuilder rb{ctx, 2}; | 102 | IPC::RequestBuilder rb{ctx, 2}; |
| 89 | rb.Push(RESULT_SUCCESS); | 103 | rb.Push(RESULT_SUCCESS); |
| 90 | 104 | ||
| 91 | LOG_WARNING(Service, "(STUBBED) called"); | 105 | LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag)); |
| 92 | } | 106 | } |
| 93 | 107 | ||
| 94 | void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) { | 108 | void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) { |
| 109 | IPC::RequestParser rp{ctx}; | ||
| 110 | |||
| 111 | bool flag = rp.Pop<bool>(); | ||
| 112 | |||
| 95 | IPC::RequestBuilder rb{ctx, 2}; | 113 | IPC::RequestBuilder rb{ctx, 2}; |
| 96 | rb.Push(RESULT_SUCCESS); | 114 | rb.Push(RESULT_SUCCESS); |
| 97 | 115 | ||
| 98 | LOG_WARNING(Service, "(STUBBED) called"); | 116 | LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag)); |
| 99 | } | 117 | } |
| 100 | 118 | ||
| 101 | void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) { | 119 | void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) { |
| 102 | // Takes 3 input u8s with each field located immediately after the previous u8, these are | 120 | // Takes 3 input u8s with each field located immediately after the previous u8, these are |
| 103 | // bool flags. No output. | 121 | // bool flags. No output. |
| 122 | IPC::RequestParser rp{ctx}; | ||
| 123 | |||
| 124 | bool enabled = rp.Pop<bool>(); | ||
| 104 | 125 | ||
| 105 | IPC::RequestBuilder rb{ctx, 2}; | 126 | IPC::RequestBuilder rb{ctx, 2}; |
| 106 | rb.Push(RESULT_SUCCESS); | 127 | rb.Push(RESULT_SUCCESS); |
| 107 | 128 | ||
| 108 | LOG_WARNING(Service, "(STUBBED) called"); | 129 | LOG_WARNING(Service, "(STUBBED) called enabled=%u", static_cast<u32>(enabled)); |
| 109 | } | 130 | } |
| 110 | }; | 131 | }; |
| 111 | 132 | ||
| @@ -115,6 +136,8 @@ public: | |||
| 115 | static const FunctionInfo functions[] = { | 136 | static const FunctionInfo functions[] = { |
| 116 | {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, | 137 | {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, |
| 117 | {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"}, | 138 | {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"}, |
| 139 | {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"}, | ||
| 140 | {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"}, | ||
| 118 | {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"}, | 141 | {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"}, |
| 119 | }; | 142 | }; |
| 120 | RegisterHandlers(functions); | 143 | RegisterHandlers(functions); |
| @@ -123,6 +146,16 @@ public: | |||
| 123 | } | 146 | } |
| 124 | 147 | ||
| 125 | private: | 148 | private: |
| 149 | enum class FocusState : u8 { | ||
| 150 | InFocus = 1, | ||
| 151 | NotInFocus = 2, | ||
| 152 | }; | ||
| 153 | |||
| 154 | enum class OperationMode : u8 { | ||
| 155 | Handheld = 0, | ||
| 156 | Docked = 1, | ||
| 157 | }; | ||
| 158 | |||
| 126 | void GetEventHandle(Kernel::HLERequestContext& ctx) { | 159 | void GetEventHandle(Kernel::HLERequestContext& ctx) { |
| 127 | event->Signal(); | 160 | event->Signal(); |
| 128 | 161 | ||
| @@ -144,7 +177,23 @@ private: | |||
| 144 | void GetCurrentFocusState(Kernel::HLERequestContext& ctx) { | 177 | void GetCurrentFocusState(Kernel::HLERequestContext& ctx) { |
| 145 | IPC::RequestBuilder rb{ctx, 3}; | 178 | IPC::RequestBuilder rb{ctx, 3}; |
| 146 | rb.Push(RESULT_SUCCESS); | 179 | rb.Push(RESULT_SUCCESS); |
| 147 | rb.Push<u32>(1); // 1: In focus, 2/3: Out of focus(running in "background") | 180 | rb.Push(static_cast<u8>(FocusState::InFocus)); |
| 181 | |||
| 182 | LOG_WARNING(Service, "(STUBBED) called"); | ||
| 183 | } | ||
| 184 | |||
| 185 | void GetOperationMode(Kernel::HLERequestContext& ctx) { | ||
| 186 | IPC::RequestBuilder rb{ctx, 3}; | ||
| 187 | rb.Push(RESULT_SUCCESS); | ||
| 188 | rb.Push(static_cast<u8>(OperationMode::Handheld)); | ||
| 189 | |||
| 190 | LOG_WARNING(Service, "(STUBBED) called"); | ||
| 191 | } | ||
| 192 | |||
| 193 | void GetPerformanceMode(Kernel::HLERequestContext& ctx) { | ||
| 194 | IPC::RequestBuilder rb{ctx, 3}; | ||
| 195 | rb.Push(RESULT_SUCCESS); | ||
| 196 | rb.Push(static_cast<u32>(APM::PerformanceMode::Handheld)); | ||
| 148 | 197 | ||
| 149 | LOG_WARNING(Service, "(STUBBED) called"); | 198 | LOG_WARNING(Service, "(STUBBED) called"); |
| 150 | } | 199 | } |
| @@ -160,6 +209,7 @@ public: | |||
| 160 | {66, &IApplicationFunctions::InitializeGamePlayRecording, | 209 | {66, &IApplicationFunctions::InitializeGamePlayRecording, |
| 161 | "InitializeGamePlayRecording"}, | 210 | "InitializeGamePlayRecording"}, |
| 162 | {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"}, | 211 | {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"}, |
| 212 | {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"}, | ||
| 163 | }; | 213 | }; |
| 164 | RegisterHandlers(functions); | 214 | RegisterHandlers(functions); |
| 165 | } | 215 | } |
| @@ -187,6 +237,15 @@ private: | |||
| 187 | void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) { | 237 | void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) { |
| 188 | IPC::RequestBuilder rb{ctx, 2}; | 238 | IPC::RequestBuilder rb{ctx, 2}; |
| 189 | rb.Push(RESULT_SUCCESS); | 239 | rb.Push(RESULT_SUCCESS); |
| 240 | |||
| 241 | LOG_WARNING(Service, "(STUBBED) called"); | ||
| 242 | } | ||
| 243 | |||
| 244 | void NotifyRunning(Kernel::HLERequestContext& ctx) { | ||
| 245 | IPC::RequestBuilder rb{ctx, 3}; | ||
| 246 | rb.Push(RESULT_SUCCESS); | ||
| 247 | rb.Push<u8>(0); // Unknown, seems to be ignored by official processes | ||
| 248 | |||
| 190 | LOG_WARNING(Service, "(STUBBED) called"); | 249 | LOG_WARNING(Service, "(STUBBED) called"); |
| 191 | } | 250 | } |
| 192 | }; | 251 | }; |
diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index 957abdd66..66d94ff52 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp | |||
| @@ -13,12 +13,54 @@ void InstallInterfaces(SM::ServiceManager& service_manager) { | |||
| 13 | std::make_shared<APM>()->InstallAsService(service_manager); | 13 | std::make_shared<APM>()->InstallAsService(service_manager); |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | class ISession final : public ServiceFramework<ISession> { | ||
| 17 | public: | ||
| 18 | ISession() : ServiceFramework("ISession") { | ||
| 19 | static const FunctionInfo functions[] = { | ||
| 20 | {0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"}, | ||
| 21 | {1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"}, | ||
| 22 | }; | ||
| 23 | RegisterHandlers(functions); | ||
| 24 | } | ||
| 25 | |||
| 26 | private: | ||
| 27 | void SetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { | ||
| 28 | IPC::RequestParser rp{ctx}; | ||
| 29 | |||
| 30 | auto mode = static_cast<PerformanceMode>(rp.Pop<u32>()); | ||
| 31 | u32 config = rp.Pop<u32>(); | ||
| 32 | |||
| 33 | IPC::RequestBuilder rb{ctx, 2}; | ||
| 34 | rb.Push(RESULT_SUCCESS); | ||
| 35 | |||
| 36 | LOG_WARNING(Service, "(STUBBED) called mode=%u config=%u", static_cast<u32>(mode), config); | ||
| 37 | } | ||
| 38 | |||
| 39 | void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { | ||
| 40 | IPC::RequestParser rp{ctx}; | ||
| 41 | |||
| 42 | auto mode = static_cast<PerformanceMode>(rp.Pop<u32>()); | ||
| 43 | |||
| 44 | IPC::RequestBuilder rb{ctx, 3}; | ||
| 45 | rb.Push(RESULT_SUCCESS); | ||
| 46 | rb.Push<u32>(0); // Performance configuration | ||
| 47 | |||
| 48 | LOG_WARNING(Service, "(STUBBED) called mode=%u", static_cast<u32>(mode)); | ||
| 49 | } | ||
| 50 | }; | ||
| 51 | |||
| 16 | APM::APM() : ServiceFramework("apm") { | 52 | APM::APM() : ServiceFramework("apm") { |
| 17 | static const FunctionInfo functions[] = { | 53 | static const FunctionInfo functions[] = { |
| 18 | {0x00000000, nullptr, "OpenSession"}, {0x00000001, nullptr, "GetPerformanceMode"}, | 54 | {0x00000000, &APM::OpenSession, "OpenSession"}, {0x00000001, nullptr, "GetPerformanceMode"}, |
| 19 | }; | 55 | }; |
| 20 | RegisterHandlers(functions); | 56 | RegisterHandlers(functions); |
| 21 | } | 57 | } |
| 22 | 58 | ||
| 59 | void APM::OpenSession(Kernel::HLERequestContext& ctx) { | ||
| 60 | IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; | ||
| 61 | rb.Push(RESULT_SUCCESS); | ||
| 62 | rb.PushIpcInterface<ISession>(); | ||
| 63 | } | ||
| 64 | |||
| 23 | } // namespace APM | 65 | } // namespace APM |
| 24 | } // namespace Service | 66 | } // namespace Service |
diff --git a/src/core/hle/service/apm/apm.h b/src/core/hle/service/apm/apm.h index 377db71a4..90a1afbbc 100644 --- a/src/core/hle/service/apm/apm.h +++ b/src/core/hle/service/apm/apm.h | |||
| @@ -9,10 +9,18 @@ | |||
| 9 | namespace Service { | 9 | namespace Service { |
| 10 | namespace APM { | 10 | namespace APM { |
| 11 | 11 | ||
| 12 | enum class PerformanceMode : u8 { | ||
| 13 | Handheld = 0, | ||
| 14 | Docked = 1, | ||
| 15 | }; | ||
| 16 | |||
| 12 | class APM final : public ServiceFramework<APM> { | 17 | class APM final : public ServiceFramework<APM> { |
| 13 | public: | 18 | public: |
| 14 | APM(); | 19 | APM(); |
| 15 | ~APM() = default; | 20 | ~APM() = default; |
| 21 | |||
| 22 | private: | ||
| 23 | void OpenSession(Kernel::HLERequestContext& ctx); | ||
| 16 | }; | 24 | }; |
| 17 | 25 | ||
| 18 | /// Registers all AM services with the specified service manager. | 26 | /// Registers all AM services with the specified service manager. |
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h index 1ee2787c6..5ee33b3d6 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | 9 | ||
| 10 | namespace Service { | 10 | namespace Service { |
| 11 | namespace NVDRV { | 11 | namespace Nvidia { |
| 12 | namespace Devices { | 12 | namespace Devices { |
| 13 | 13 | ||
| 14 | /// Represents an abstract nvidia device node. It is to be subclassed by concrete device nodes to | 14 | /// Represents an abstract nvidia device node. It is to be subclassed by concrete device nodes to |
| @@ -29,5 +29,5 @@ public: | |||
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | } // namespace Devices | 31 | } // namespace Devices |
| 32 | } // namespace NVDRV | 32 | } // namespace Nvidia |
| 33 | } // namespace Service | 33 | } // namespace Service |
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 992f70b45..c42a65b36 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include "video_core/video_core.h" | 10 | #include "video_core/video_core.h" |
| 11 | 11 | ||
| 12 | namespace Service { | 12 | namespace Service { |
| 13 | namespace NVDRV { | 13 | namespace Nvidia { |
| 14 | namespace Devices { | 14 | namespace Devices { |
| 15 | 15 | ||
| 16 | u32 nvdisp_disp0::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | 16 | u32 nvdisp_disp0::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { |
| @@ -32,5 +32,5 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 | |||
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | } // namespace Devices | 34 | } // namespace Devices |
| 35 | } // namespace NVDRV | 35 | } // namespace Nvidia |
| 36 | } // namespace Service | 36 | } // namespace Service |
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h index 601068af1..f5f9de3f4 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 10 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
| 11 | 11 | ||
| 12 | namespace Service { | 12 | namespace Service { |
| 13 | namespace NVDRV { | 13 | namespace Nvidia { |
| 14 | namespace Devices { | 14 | namespace Devices { |
| 15 | 15 | ||
| 16 | class nvmap; | 16 | class nvmap; |
| @@ -30,5 +30,5 @@ private: | |||
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | } // namespace Devices | 32 | } // namespace Devices |
| 33 | } // namespace NVDRV | 33 | } // namespace Nvidia |
| 34 | } // namespace Service | 34 | } // namespace Service |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index c7bf79050..9db08339a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | 7 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" |
| 8 | 8 | ||
| 9 | namespace Service { | 9 | namespace Service { |
| 10 | namespace NVDRV { | 10 | namespace Nvidia { |
| 11 | namespace Devices { | 11 | namespace Devices { |
| 12 | 12 | ||
| 13 | u32 nvhost_as_gpu::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | 13 | u32 nvhost_as_gpu::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { |
| @@ -16,5 +16,5 @@ u32 nvhost_as_gpu::ioctl(u32 command, const std::vector<u8>& input, std::vector< | |||
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | } // namespace Devices | 18 | } // namespace Devices |
| 19 | } // namespace NVDRV | 19 | } // namespace Nvidia |
| 20 | } // namespace Service | 20 | } // namespace Service |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index 6f441b020..01f8861c8 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 9 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
| 10 | 10 | ||
| 11 | namespace Service { | 11 | namespace Service { |
| 12 | namespace NVDRV { | 12 | namespace Nvidia { |
| 13 | namespace Devices { | 13 | namespace Devices { |
| 14 | 14 | ||
| 15 | class nvhost_as_gpu final : public nvdevice { | 15 | class nvhost_as_gpu final : public nvdevice { |
| @@ -21,5 +21,5 @@ public: | |||
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | } // namespace Devices | 23 | } // namespace Devices |
| 24 | } // namespace NVDRV | 24 | } // namespace Nvidia |
| 25 | } // namespace Service | 25 | } // namespace Service |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 2d6f30e3e..d37b5b159 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "core/hle/service/nvdrv/devices/nvmap.h" | 9 | #include "core/hle/service/nvdrv/devices/nvmap.h" |
| 10 | 10 | ||
| 11 | namespace Service { | 11 | namespace Service { |
| 12 | namespace NVDRV { | 12 | namespace Nvidia { |
| 13 | namespace Devices { | 13 | namespace Devices { |
| 14 | 14 | ||
| 15 | VAddr nvmap::GetObjectAddress(u32 handle) const { | 15 | VAddr nvmap::GetObjectAddress(u32 handle) const { |
| @@ -151,5 +151,5 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | } // namespace Devices | 153 | } // namespace Devices |
| 154 | } // namespace NVDRV | 154 | } // namespace Nvidia |
| 155 | } // namespace Service | 155 | } // namespace Service |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h index e74f356e5..6954c0324 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 13 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
| 14 | 14 | ||
| 15 | namespace Service { | 15 | namespace Service { |
| 16 | namespace NVDRV { | 16 | namespace Nvidia { |
| 17 | namespace Devices { | 17 | namespace Devices { |
| 18 | 18 | ||
| 19 | class nvmap final : public nvdevice { | 19 | class nvmap final : public nvdevice { |
| @@ -104,5 +104,5 @@ private: | |||
| 104 | }; | 104 | }; |
| 105 | 105 | ||
| 106 | } // namespace Devices | 106 | } // namespace Devices |
| 107 | } // namespace NVDRV | 107 | } // namespace Nvidia |
| 108 | } // namespace Service | 108 | } // namespace Service |
diff --git a/src/core/hle/service/nvdrv/nvdrv_a.cpp b/src/core/hle/service/nvdrv/interface.cpp index 84d89cb49..0670ca155 100644 --- a/src/core/hle/service/nvdrv/nvdrv_a.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp | |||
| @@ -4,35 +4,27 @@ | |||
| 4 | 4 | ||
| 5 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 6 | #include "core/hle/ipc_helpers.h" | 6 | #include "core/hle/ipc_helpers.h" |
| 7 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 7 | #include "core/hle/service/nvdrv/interface.h" |
| 8 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | ||
| 9 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | ||
| 10 | #include "core/hle/service/nvdrv/devices/nvmap.h" | ||
| 11 | #include "core/hle/service/nvdrv/nvdrv.h" | 8 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 12 | #include "core/hle/service/nvdrv/nvdrv_a.h" | ||
| 13 | 9 | ||
| 14 | namespace Service { | 10 | namespace Service { |
| 15 | namespace NVDRV { | 11 | namespace Nvidia { |
| 16 | 12 | ||
| 17 | void NVDRV_A::Open(Kernel::HLERequestContext& ctx) { | 13 | void NVDRV::Open(Kernel::HLERequestContext& ctx) { |
| 18 | LOG_WARNING(Service, "(STUBBED) called"); | 14 | LOG_WARNING(Service, "(STUBBED) called"); |
| 19 | 15 | ||
| 20 | auto buffer = ctx.BufferDescriptorA()[0]; | 16 | auto buffer = ctx.BufferDescriptorA()[0]; |
| 21 | 17 | ||
| 22 | std::string device_name = Memory::ReadCString(buffer.Address(), buffer.Size()); | 18 | std::string device_name = Memory::ReadCString(buffer.Address(), buffer.Size()); |
| 23 | 19 | ||
| 24 | auto device = devices[device_name]; | 20 | u32 fd = nvdrv->Open(device_name); |
| 25 | u32 fd = next_fd++; | ||
| 26 | |||
| 27 | open_files[fd] = device; | ||
| 28 | |||
| 29 | IPC::RequestBuilder rb{ctx, 4}; | 21 | IPC::RequestBuilder rb{ctx, 4}; |
| 30 | rb.Push(RESULT_SUCCESS); | 22 | rb.Push(RESULT_SUCCESS); |
| 31 | rb.Push<u32>(fd); | 23 | rb.Push<u32>(fd); |
| 32 | rb.Push<u32>(0); | 24 | rb.Push<u32>(0); |
| 33 | } | 25 | } |
| 34 | 26 | ||
| 35 | void NVDRV_A::Ioctl(Kernel::HLERequestContext& ctx) { | 27 | void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { |
| 36 | LOG_WARNING(Service, "(STUBBED) called"); | 28 | LOG_WARNING(Service, "(STUBBED) called"); |
| 37 | 29 | ||
| 38 | IPC::RequestParser rp{ctx}; | 30 | IPC::RequestParser rp{ctx}; |
| @@ -46,11 +38,8 @@ void NVDRV_A::Ioctl(Kernel::HLERequestContext& ctx) { | |||
| 46 | std::vector<u8> output(output_buffer.Size()); | 38 | std::vector<u8> output(output_buffer.Size()); |
| 47 | 39 | ||
| 48 | Memory::ReadBlock(input_buffer.Address(), input.data(), input_buffer.Size()); | 40 | Memory::ReadBlock(input_buffer.Address(), input.data(), input_buffer.Size()); |
| 49 | auto itr = open_files.find(fd); | ||
| 50 | ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); | ||
| 51 | 41 | ||
| 52 | auto device = itr->second; | 42 | u32 nv_result = nvdrv->Ioctl(fd, command, input, output); |
| 53 | u32 nv_result = device->ioctl(command, input, output); | ||
| 54 | 43 | ||
| 55 | Memory::WriteBlock(output_buffer.Address(), output.data(), output_buffer.Size()); | 44 | Memory::WriteBlock(output_buffer.Address(), output.data(), output_buffer.Size()); |
| 56 | 45 | ||
| @@ -59,26 +48,22 @@ void NVDRV_A::Ioctl(Kernel::HLERequestContext& ctx) { | |||
| 59 | rb.Push(nv_result); | 48 | rb.Push(nv_result); |
| 60 | } | 49 | } |
| 61 | 50 | ||
| 62 | void NVDRV_A::Initialize(Kernel::HLERequestContext& ctx) { | 51 | void NVDRV::Initialize(Kernel::HLERequestContext& ctx) { |
| 63 | LOG_WARNING(Service, "(STUBBED) called"); | 52 | LOG_WARNING(Service, "(STUBBED) called"); |
| 64 | IPC::RequestBuilder rb{ctx, 3}; | 53 | IPC::RequestBuilder rb{ctx, 3}; |
| 65 | rb.Push(RESULT_SUCCESS); | 54 | rb.Push(RESULT_SUCCESS); |
| 66 | rb.Push<u32>(0); | 55 | rb.Push<u32>(0); |
| 67 | } | 56 | } |
| 68 | 57 | ||
| 69 | NVDRV_A::NVDRV_A() : ServiceFramework("nvdrv:a") { | 58 | NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name) |
| 59 | : ServiceFramework(name), nvdrv(std::move(nvdrv)) { | ||
| 70 | static const FunctionInfo functions[] = { | 60 | static const FunctionInfo functions[] = { |
| 71 | {0, &NVDRV_A::Open, "Open"}, | 61 | {0, &NVDRV::Open, "Open"}, |
| 72 | {1, &NVDRV_A::Ioctl, "Ioctl"}, | 62 | {1, &NVDRV::Ioctl, "Ioctl"}, |
| 73 | {3, &NVDRV_A::Initialize, "Initialize"}, | 63 | {3, &NVDRV::Initialize, "Initialize"}, |
| 74 | }; | 64 | }; |
| 75 | RegisterHandlers(functions); | 65 | RegisterHandlers(functions); |
| 76 | |||
| 77 | auto nvmap_dev = std::make_shared<Devices::nvmap>(); | ||
| 78 | devices["/dev/nvhost-as-gpu"] = std::make_shared<Devices::nvhost_as_gpu>(); | ||
| 79 | devices["/dev/nvmap"] = nvmap_dev; | ||
| 80 | devices["/dev/nvdisp_disp0"] = std::make_shared<Devices::nvdisp_disp0>(nvmap_dev); | ||
| 81 | } | 66 | } |
| 82 | 67 | ||
| 83 | } // namespace NVDRV | 68 | } // namespace Nvidia |
| 84 | } // namespace Service | 69 | } // namespace Service |
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h new file mode 100644 index 000000000..8c95b7217 --- /dev/null +++ b/src/core/hle/service/nvdrv/interface.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <string> | ||
| 9 | #include "core/hle/service/nvdrv/nvdrv.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | |||
| 12 | namespace Service { | ||
| 13 | namespace Nvidia { | ||
| 14 | |||
| 15 | class NVDRV final : public ServiceFramework<NVDRV> { | ||
| 16 | public: | ||
| 17 | NVDRV(std::shared_ptr<Module> nvdrv, const char* name); | ||
| 18 | ~NVDRV() = default; | ||
| 19 | |||
| 20 | private: | ||
| 21 | void Open(Kernel::HLERequestContext& ctx); | ||
| 22 | void Ioctl(Kernel::HLERequestContext& ctx); | ||
| 23 | void Initialize(Kernel::HLERequestContext& ctx); | ||
| 24 | |||
| 25 | std::shared_ptr<Module> nvdrv; | ||
| 26 | }; | ||
| 27 | |||
| 28 | } // namespace Nvidia | ||
| 29 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index c874e6395..cf525a875 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp | |||
| @@ -2,19 +2,52 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/hle/ipc_helpers.h" | ||
| 6 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | ||
| 7 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | ||
| 8 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | ||
| 9 | #include "core/hle/service/nvdrv/devices/nvmap.h" | ||
| 5 | #include "core/hle/service/nvdrv/nvdrv.h" | 10 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 6 | #include "core/hle/service/nvdrv/nvdrv_a.h" | 11 | #include "core/hle/service/nvdrv/interface.h" |
| 7 | 12 | ||
| 8 | namespace Service { | 13 | namespace Service { |
| 9 | namespace NVDRV { | 14 | namespace Nvidia { |
| 10 | 15 | ||
| 11 | std::weak_ptr<NVDRV_A> nvdrv_a; | 16 | std::weak_ptr<Module> nvdrv; |
| 12 | 17 | ||
| 13 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 18 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
| 14 | auto nvdrv = std::make_shared<NVDRV_A>(); | 19 | auto module_ = std::make_shared<Module>(); |
| 15 | nvdrv->InstallAsService(service_manager); | 20 | std::make_shared<NVDRV>(module_, "nvdrv")->InstallAsService(service_manager); |
| 16 | nvdrv_a = nvdrv; | 21 | std::make_shared<NVDRV>(module_, "nvdrv:a")->InstallAsService(service_manager); |
| 22 | nvdrv = module_; | ||
| 17 | } | 23 | } |
| 18 | 24 | ||
| 19 | } // namespace NVDRV | 25 | Module::Module() { |
| 26 | auto nvmap_dev = std::make_shared<Devices::nvmap>(); | ||
| 27 | devices["/dev/nvhost-as-gpu"] = std::make_shared<Devices::nvhost_as_gpu>(); | ||
| 28 | devices["/dev/nvmap"] = nvmap_dev; | ||
| 29 | devices["/dev/nvdisp_disp0"] = std::make_shared<Devices::nvdisp_disp0>(nvmap_dev); | ||
| 30 | } | ||
| 31 | |||
| 32 | u32 Module::Open(std::string device_name) { | ||
| 33 | ASSERT_MSG(devices.find(device_name) != devices.end(), "Trying to open unknown device %s", | ||
| 34 | device_name.c_str()); | ||
| 35 | |||
| 36 | auto device = devices[device_name]; | ||
| 37 | u32 fd = next_fd++; | ||
| 38 | |||
| 39 | open_files[fd] = device; | ||
| 40 | |||
| 41 | return fd; | ||
| 42 | } | ||
| 43 | |||
| 44 | u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 45 | auto itr = open_files.find(fd); | ||
| 46 | ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); | ||
| 47 | |||
| 48 | auto device = itr->second; | ||
| 49 | return device->ioctl(command, input, output); | ||
| 50 | } | ||
| 51 | |||
| 52 | } // namespace Nvidia | ||
| 20 | } // namespace Service | 53 | } // namespace Service |
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index a1c050416..1940ced99 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h | |||
| @@ -11,110 +11,46 @@ | |||
| 11 | #include "core/hle/service/service.h" | 11 | #include "core/hle/service/service.h" |
| 12 | 12 | ||
| 13 | namespace Service { | 13 | namespace Service { |
| 14 | namespace NVDRV { | 14 | namespace Nvidia { |
| 15 | 15 | ||
| 16 | class nvdevice { | 16 | namespace Devices { |
| 17 | public: | 17 | class nvdevice; |
| 18 | virtual ~nvdevice() = default; | 18 | } |
| 19 | |||
| 20 | virtual u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) = 0; | ||
| 21 | }; | ||
| 22 | 19 | ||
| 23 | class nvmap : public nvdevice { | 20 | class Module final { |
| 24 | public: | 21 | public: |
| 25 | /// Returns the allocated address of an nvmap object given its handle. | 22 | Module(); |
| 26 | VAddr GetObjectAddress(u32 handle) const; | 23 | ~Module() = default; |
| 27 | 24 | ||
| 28 | u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override; | 25 | /// Returns a pointer to one of the available devices, identified by its name. |
| 26 | template <typename T> | ||
| 27 | std::shared_ptr<T> GetDevice(std::string name) { | ||
| 28 | auto itr = devices.find(name); | ||
| 29 | if (itr == devices.end()) | ||
| 30 | return nullptr; | ||
| 31 | return std::static_pointer_cast<T>(itr->second); | ||
| 32 | } | ||
| 33 | |||
| 34 | /// Opens a device node and returns a file descriptor to it. | ||
| 35 | u32 Open(std::string device_name); | ||
| 36 | /// Sends an ioctl command to the specified file descriptor. | ||
| 37 | u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output); | ||
| 29 | 38 | ||
| 30 | private: | 39 | private: |
| 31 | // Represents an nvmap object. | 40 | /// Id to use for the next open file descriptor. |
| 32 | struct Object { | 41 | u32 next_fd = 1; |
| 33 | enum class Status { Created, Allocated }; | ||
| 34 | u32 id; | ||
| 35 | u32 size; | ||
| 36 | u32 flags; | ||
| 37 | u32 align; | ||
| 38 | u8 kind; | ||
| 39 | VAddr addr; | ||
| 40 | Status status; | ||
| 41 | }; | ||
| 42 | |||
| 43 | u32 next_handle = 1; | ||
| 44 | u32 next_id = 1; | ||
| 45 | std::unordered_map<u32, std::shared_ptr<Object>> handles; | ||
| 46 | |||
| 47 | enum IoctlCommands { | ||
| 48 | IocCreateCommand = 0xC0080101, | ||
| 49 | IocFromIdCommand = 0xC0080103, | ||
| 50 | IocAllocCommand = 0xC0200104, | ||
| 51 | IocParamCommand = 0xC00C0109, | ||
| 52 | IocGetIdCommand = 0xC008010E | ||
| 53 | }; | ||
| 54 | |||
| 55 | struct IocCreateParams { | ||
| 56 | // Input | ||
| 57 | u32_le size; | ||
| 58 | // Output | ||
| 59 | u32_le handle; | ||
| 60 | }; | ||
| 61 | |||
| 62 | struct IocAllocParams { | ||
| 63 | // Input | ||
| 64 | u32_le handle; | ||
| 65 | u32_le heap_mask; | ||
| 66 | u32_le flags; | ||
| 67 | u32_le align; | ||
| 68 | u8 kind; | ||
| 69 | INSERT_PADDING_BYTES(7); | ||
| 70 | u64_le addr; | ||
| 71 | }; | ||
| 72 | |||
| 73 | struct IocGetIdParams { | ||
| 74 | // Output | ||
| 75 | u32_le id; | ||
| 76 | // Input | ||
| 77 | u32_le handle; | ||
| 78 | }; | ||
| 79 | 42 | ||
| 80 | struct IocFromIdParams { | 43 | /// Mapping of file descriptors to the devices they reference. |
| 81 | // Input | 44 | std::unordered_map<u32, std::shared_ptr<Devices::nvdevice>> open_files; |
| 82 | u32_le id; | ||
| 83 | // Output | ||
| 84 | u32_le handle; | ||
| 85 | }; | ||
| 86 | 45 | ||
| 87 | struct IocParamParams { | 46 | /// Mapping of device node names to their implementation. |
| 88 | // Input | 47 | std::unordered_map<std::string, std::shared_ptr<Devices::nvdevice>> devices; |
| 89 | u32_le handle; | ||
| 90 | u32_le type; | ||
| 91 | // Output | ||
| 92 | u32_le value; | ||
| 93 | }; | ||
| 94 | |||
| 95 | u32 IocCreate(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 96 | u32 IocAlloc(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 97 | u32 IocGetId(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 98 | u32 IocFromId(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 99 | u32 IocParam(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 100 | }; | ||
| 101 | |||
| 102 | class nvdisp_disp0 : public nvdevice { | ||
| 103 | public: | ||
| 104 | nvdisp_disp0(std::shared_ptr<nvmap> nvmap_dev) : nvdevice(), nvmap_dev(std::move(nvmap_dev)) {} | ||
| 105 | ~nvdisp_disp0() = default; | ||
| 106 | |||
| 107 | u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override; | ||
| 108 | |||
| 109 | /// Performs a screen flip, drawing the buffer pointed to by the handle. | ||
| 110 | void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride); | ||
| 111 | |||
| 112 | private: | ||
| 113 | std::shared_ptr<nvmap> nvmap_dev; | ||
| 114 | }; | 48 | }; |
| 115 | 49 | ||
| 116 | /// Registers all NVDRV services with the specified service manager. | 50 | /// Registers all NVDRV services with the specified service manager. |
| 117 | void InstallInterfaces(SM::ServiceManager& service_manager); | 51 | void InstallInterfaces(SM::ServiceManager& service_manager); |
| 118 | 52 | ||
| 119 | } // namespace NVDRV | 53 | extern std::weak_ptr<Module> nvdrv; |
| 54 | |||
| 55 | } // namespace Nvidia | ||
| 120 | } // namespace Service | 56 | } // namespace Service |
diff --git a/src/core/hle/service/nvdrv/nvdrv_a.h b/src/core/hle/service/nvdrv/nvdrv_a.h deleted file mode 100644 index 62f10e9f6..000000000 --- a/src/core/hle/service/nvdrv/nvdrv_a.h +++ /dev/null | |||
| @@ -1,51 +0,0 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <string> | ||
| 9 | #include "core/hle/service/nvdrv/nvdrv.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | |||
| 12 | namespace Service { | ||
| 13 | namespace NVDRV { | ||
| 14 | |||
| 15 | namespace Devices { | ||
| 16 | class nvdevice; | ||
| 17 | } | ||
| 18 | |||
| 19 | class NVDRV_A final : public ServiceFramework<NVDRV_A> { | ||
| 20 | public: | ||
| 21 | NVDRV_A(); | ||
| 22 | ~NVDRV_A() = default; | ||
| 23 | |||
| 24 | /// Returns a pointer to one of the available devices, identified by its name. | ||
| 25 | template <typename T> | ||
| 26 | std::shared_ptr<T> GetDevice(std::string name) { | ||
| 27 | auto itr = devices.find(name); | ||
| 28 | if (itr == devices.end()) | ||
| 29 | return nullptr; | ||
| 30 | return std::static_pointer_cast<T>(itr->second); | ||
| 31 | } | ||
| 32 | |||
| 33 | private: | ||
| 34 | void Open(Kernel::HLERequestContext& ctx); | ||
| 35 | void Ioctl(Kernel::HLERequestContext& ctx); | ||
| 36 | void Initialize(Kernel::HLERequestContext& ctx); | ||
| 37 | |||
| 38 | /// Id to use for the next open file descriptor. | ||
| 39 | u32 next_fd = 1; | ||
| 40 | |||
| 41 | /// Mapping of file descriptors to the devices they reference. | ||
| 42 | std::unordered_map<u32, std::shared_ptr<Devices::nvdevice>> open_files; | ||
| 43 | |||
| 44 | /// Mapping of device node names to their implementation. | ||
| 45 | std::unordered_map<std::string, std::shared_ptr<Devices::nvdevice>> devices; | ||
| 46 | }; | ||
| 47 | |||
| 48 | extern std::weak_ptr<NVDRV_A> nvdrv_a; | ||
| 49 | |||
| 50 | } // namespace NVDRV | ||
| 51 | } // namespace Service | ||
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 02d434660..44623d40f 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -170,7 +170,7 @@ void Init() { | |||
| 170 | Audio::InstallInterfaces(*SM::g_service_manager); | 170 | Audio::InstallInterfaces(*SM::g_service_manager); |
| 171 | HID::InstallInterfaces(*SM::g_service_manager); | 171 | HID::InstallInterfaces(*SM::g_service_manager); |
| 172 | LM::InstallInterfaces(*SM::g_service_manager); | 172 | LM::InstallInterfaces(*SM::g_service_manager); |
| 173 | NVDRV::InstallInterfaces(*SM::g_service_manager); | 173 | Nvidia::InstallInterfaces(*SM::g_service_manager); |
| 174 | PCTL::InstallInterfaces(*SM::g_service_manager); | 174 | PCTL::InstallInterfaces(*SM::g_service_manager); |
| 175 | Time::InstallInterfaces(*SM::g_service_manager); | 175 | Time::InstallInterfaces(*SM::g_service_manager); |
| 176 | VI::InstallInterfaces(*SM::g_service_manager); | 176 | VI::InstallInterfaces(*SM::g_service_manager); |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 93ebbe75f..cae2c4466 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "core/core_timing.h" | 9 | #include "core/core_timing.h" |
| 10 | #include "core/hle/ipc_helpers.h" | 10 | #include "core/hle/ipc_helpers.h" |
| 11 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | 11 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" |
| 12 | #include "core/hle/service/nvdrv/nvdrv_a.h" | 12 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 13 | #include "core/hle/service/vi/vi.h" | 13 | #include "core/hle/service/vi/vi.h" |
| 14 | #include "core/hle/service/vi/vi_m.h" | 14 | #include "core/hle/service/vi/vi_m.h" |
| 15 | #include "video_core/renderer_base.h" | 15 | #include "video_core/renderer_base.h" |
| @@ -361,7 +361,7 @@ public: | |||
| 361 | static const FunctionInfo functions[] = { | 361 | static const FunctionInfo functions[] = { |
| 362 | {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, | 362 | {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, |
| 363 | {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, | 363 | {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, |
| 364 | {2, nullptr, "GetNativeHandle"}, | 364 | {2, &IHOSBinderDriver::GetNativeHandle, "GetNativeHandle"}, |
| 365 | {3, nullptr, "TransactParcelAuto"}, | 365 | {3, nullptr, "TransactParcelAuto"}, |
| 366 | }; | 366 | }; |
| 367 | RegisterHandlers(functions); | 367 | RegisterHandlers(functions); |
| @@ -463,6 +463,21 @@ private: | |||
| 463 | rb.Push(RESULT_SUCCESS); | 463 | rb.Push(RESULT_SUCCESS); |
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | void GetNativeHandle(Kernel::HLERequestContext& ctx) { | ||
| 467 | IPC::RequestParser rp{ctx}; | ||
| 468 | u32 id = rp.Pop<u32>(); | ||
| 469 | u32 unknown = rp.Pop<u32>(); | ||
| 470 | |||
| 471 | auto buffer_queue = nv_flinger->GetBufferQueue(id); | ||
| 472 | |||
| 473 | // TODO(Subv): Find out what this actually is. | ||
| 474 | |||
| 475 | LOG_WARNING(Service, "(STUBBED) called id=%u, unknown=%08X", id, unknown); | ||
| 476 | IPC::RequestBuilder rb{ctx, 2, 1}; | ||
| 477 | rb.Push(RESULT_SUCCESS); | ||
| 478 | rb.PushCopyObjects(buffer_queue->GetNativeHandle()); | ||
| 479 | } | ||
| 480 | |||
| 466 | std::shared_ptr<NVFlinger> nv_flinger; | 481 | std::shared_ptr<NVFlinger> nv_flinger; |
| 467 | }; | 482 | }; |
| 468 | 483 | ||
| @@ -565,6 +580,15 @@ void IApplicationDisplayService::GetManagerDisplayService(Kernel::HLERequestCont | |||
| 565 | rb.PushIpcInterface<IManagerDisplayService>(nv_flinger); | 580 | rb.PushIpcInterface<IManagerDisplayService>(nv_flinger); |
| 566 | } | 581 | } |
| 567 | 582 | ||
| 583 | void IApplicationDisplayService::GetIndirectDisplayTransactionService( | ||
| 584 | Kernel::HLERequestContext& ctx) { | ||
| 585 | LOG_WARNING(Service, "(STUBBED) called"); | ||
| 586 | |||
| 587 | IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; | ||
| 588 | rb.Push(RESULT_SUCCESS); | ||
| 589 | rb.PushIpcInterface<IHOSBinderDriver>(nv_flinger); | ||
| 590 | } | ||
| 591 | |||
| 568 | void IApplicationDisplayService::OpenDisplay(Kernel::HLERequestContext& ctx) { | 592 | void IApplicationDisplayService::OpenDisplay(Kernel::HLERequestContext& ctx) { |
| 569 | LOG_WARNING(Service, "(STUBBED) called"); | 593 | LOG_WARNING(Service, "(STUBBED) called"); |
| 570 | IPC::RequestParser rp{ctx}; | 594 | IPC::RequestParser rp{ctx}; |
| @@ -580,6 +604,15 @@ void IApplicationDisplayService::OpenDisplay(Kernel::HLERequestContext& ctx) { | |||
| 580 | rb.Push<u64>(nv_flinger->OpenDisplay(name)); | 604 | rb.Push<u64>(nv_flinger->OpenDisplay(name)); |
| 581 | } | 605 | } |
| 582 | 606 | ||
| 607 | void IApplicationDisplayService::CloseDisplay(Kernel::HLERequestContext& ctx) { | ||
| 608 | LOG_WARNING(Service, "(STUBBED) called"); | ||
| 609 | IPC::RequestParser rp{ctx}; | ||
| 610 | u64 display_id = rp.Pop<u64>(); | ||
| 611 | |||
| 612 | IPC::RequestBuilder rb = rp.MakeBuilder(4, 0, 0, 0); | ||
| 613 | rb.Push(RESULT_SUCCESS); | ||
| 614 | } | ||
| 615 | |||
| 583 | void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) { | 616 | void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) { |
| 584 | LOG_WARNING(Service, "(STUBBED) called"); | 617 | LOG_WARNING(Service, "(STUBBED) called"); |
| 585 | IPC::RequestParser rp{ctx}; | 618 | IPC::RequestParser rp{ctx}; |
| @@ -605,6 +638,40 @@ void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) { | |||
| 605 | rb.Push<u64>(data.size()); | 638 | rb.Push<u64>(data.size()); |
| 606 | } | 639 | } |
| 607 | 640 | ||
| 641 | void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx) { | ||
| 642 | LOG_WARNING(Service, "(STUBBED) called"); | ||
| 643 | |||
| 644 | IPC::RequestParser rp{ctx}; | ||
| 645 | u32 flags = rp.Pop<u32>(); | ||
| 646 | u64 display_id = rp.Pop<u64>(); | ||
| 647 | |||
| 648 | auto& buffer = ctx.BufferDescriptorB()[0]; | ||
| 649 | |||
| 650 | // TODO(Subv): What's the difference between a Stray and a Managed layer? | ||
| 651 | |||
| 652 | u64 layer_id = nv_flinger->CreateLayer(display_id); | ||
| 653 | u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id); | ||
| 654 | |||
| 655 | NativeWindow native_window{buffer_queue_id}; | ||
| 656 | auto data = native_window.Serialize(); | ||
| 657 | Memory::WriteBlock(buffer.Address(), data.data(), data.size()); | ||
| 658 | |||
| 659 | IPC::RequestBuilder rb = rp.MakeBuilder(6, 0, 0, 0); | ||
| 660 | rb.Push(RESULT_SUCCESS); | ||
| 661 | rb.Push(layer_id); | ||
| 662 | rb.Push<u64>(data.size()); | ||
| 663 | } | ||
| 664 | |||
| 665 | void IApplicationDisplayService::DestroyStrayLayer(Kernel::HLERequestContext& ctx) { | ||
| 666 | LOG_WARNING(Service, "(STUBBED) called"); | ||
| 667 | |||
| 668 | IPC::RequestParser rp{ctx}; | ||
| 669 | u64 layer_id = rp.Pop<u64>(); | ||
| 670 | |||
| 671 | IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 0, 0); | ||
| 672 | rb.Push(RESULT_SUCCESS); | ||
| 673 | } | ||
| 674 | |||
| 608 | void IApplicationDisplayService::SetLayerScalingMode(Kernel::HLERequestContext& ctx) { | 675 | void IApplicationDisplayService::SetLayerScalingMode(Kernel::HLERequestContext& ctx) { |
| 609 | LOG_WARNING(Service, "(STUBBED) called"); | 676 | LOG_WARNING(Service, "(STUBBED) called"); |
| 610 | IPC::RequestParser rp{ctx}; | 677 | IPC::RequestParser rp{ctx}; |
| @@ -633,11 +700,15 @@ IApplicationDisplayService::IApplicationDisplayService(std::shared_ptr<NVFlinger | |||
| 633 | {100, &IApplicationDisplayService::GetRelayService, "GetRelayService"}, | 700 | {100, &IApplicationDisplayService::GetRelayService, "GetRelayService"}, |
| 634 | {101, &IApplicationDisplayService::GetSystemDisplayService, "GetSystemDisplayService"}, | 701 | {101, &IApplicationDisplayService::GetSystemDisplayService, "GetSystemDisplayService"}, |
| 635 | {102, &IApplicationDisplayService::GetManagerDisplayService, "GetManagerDisplayService"}, | 702 | {102, &IApplicationDisplayService::GetManagerDisplayService, "GetManagerDisplayService"}, |
| 636 | {103, nullptr, "GetIndirectDisplayTransactionService"}, | 703 | {103, &IApplicationDisplayService::GetIndirectDisplayTransactionService, |
| 704 | "GetIndirectDisplayTransactionService"}, | ||
| 637 | {1000, nullptr, "ListDisplays"}, | 705 | {1000, nullptr, "ListDisplays"}, |
| 638 | {1010, &IApplicationDisplayService::OpenDisplay, "OpenDisplay"}, | 706 | {1010, &IApplicationDisplayService::OpenDisplay, "OpenDisplay"}, |
| 707 | {1020, &IApplicationDisplayService::CloseDisplay, "CloseDisplay"}, | ||
| 639 | {2101, &IApplicationDisplayService::SetLayerScalingMode, "SetLayerScalingMode"}, | 708 | {2101, &IApplicationDisplayService::SetLayerScalingMode, "SetLayerScalingMode"}, |
| 640 | {2020, &IApplicationDisplayService::OpenLayer, "OpenLayer"}, | 709 | {2020, &IApplicationDisplayService::OpenLayer, "OpenLayer"}, |
| 710 | {2030, &IApplicationDisplayService::CreateStrayLayer, "CreateStrayLayer"}, | ||
| 711 | {2031, &IApplicationDisplayService::DestroyStrayLayer, "DestroyStrayLayer"}, | ||
| 641 | {5202, &IApplicationDisplayService::GetDisplayVsyncEvent, "GetDisplayVsyncEvent"}, | 712 | {5202, &IApplicationDisplayService::GetDisplayVsyncEvent, "GetDisplayVsyncEvent"}, |
| 642 | }; | 713 | }; |
| 643 | RegisterHandlers(functions); | 714 | RegisterHandlers(functions); |
| @@ -763,12 +834,12 @@ void NVFlinger::Compose() { | |||
| 763 | auto& igbp_buffer = buffer->igbp_buffer; | 834 | auto& igbp_buffer = buffer->igbp_buffer; |
| 764 | 835 | ||
| 765 | // Now send the buffer to the GPU for drawing. | 836 | // Now send the buffer to the GPU for drawing. |
| 766 | auto nvdrv = NVDRV::nvdrv_a.lock(); | 837 | auto nvdrv = Nvidia::nvdrv.lock(); |
| 767 | ASSERT(nvdrv); | 838 | ASSERT(nvdrv); |
| 768 | 839 | ||
| 769 | // TODO(Subv): Support more than just disp0. The display device selection is probably based | 840 | // TODO(Subv): Support more than just disp0. The display device selection is probably based |
| 770 | // on which display we're drawing (Default, Internal, External, etc) | 841 | // on which display we're drawing (Default, Internal, External, etc) |
| 771 | auto nvdisp = nvdrv->GetDevice<NVDRV::Devices::nvdisp_disp0>("/dev/nvdisp_disp0"); | 842 | auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>("/dev/nvdisp_disp0"); |
| 772 | ASSERT(nvdisp); | 843 | ASSERT(nvdisp); |
| 773 | 844 | ||
| 774 | nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, | 845 | nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, |
| @@ -778,7 +849,9 @@ void NVFlinger::Compose() { | |||
| 778 | } | 849 | } |
| 779 | } | 850 | } |
| 780 | 851 | ||
| 781 | BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {} | 852 | BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { |
| 853 | native_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "BufferQueue NativeHandle"); | ||
| 854 | } | ||
| 782 | 855 | ||
| 783 | void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) { | 856 | void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) { |
| 784 | Buffer buffer{}; | 857 | Buffer buffer{}; |
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h index 10e894f8c..81d4f3daa 100644 --- a/src/core/hle/service/vi/vi.h +++ b/src/core/hle/service/vi/vi.h | |||
| @@ -59,11 +59,16 @@ public: | |||
| 59 | return id; | 59 | return id; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | Kernel::SharedPtr<Kernel::Event> GetNativeHandle() const { | ||
| 63 | return native_handle; | ||
| 64 | } | ||
| 65 | |||
| 62 | private: | 66 | private: |
| 63 | u32 id; | 67 | u32 id; |
| 64 | u64 layer_id; | 68 | u64 layer_id; |
| 65 | 69 | ||
| 66 | std::vector<Buffer> queue; | 70 | std::vector<Buffer> queue; |
| 71 | Kernel::SharedPtr<Kernel::Event> native_handle; | ||
| 67 | }; | 72 | }; |
| 68 | 73 | ||
| 69 | struct Layer { | 74 | struct Layer { |
| @@ -138,9 +143,13 @@ private: | |||
| 138 | void GetRelayService(Kernel::HLERequestContext& ctx); | 143 | void GetRelayService(Kernel::HLERequestContext& ctx); |
| 139 | void GetSystemDisplayService(Kernel::HLERequestContext& ctx); | 144 | void GetSystemDisplayService(Kernel::HLERequestContext& ctx); |
| 140 | void GetManagerDisplayService(Kernel::HLERequestContext& ctx); | 145 | void GetManagerDisplayService(Kernel::HLERequestContext& ctx); |
| 146 | void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx); | ||
| 141 | void OpenDisplay(Kernel::HLERequestContext& ctx); | 147 | void OpenDisplay(Kernel::HLERequestContext& ctx); |
| 148 | void CloseDisplay(Kernel::HLERequestContext& ctx); | ||
| 142 | void SetLayerScalingMode(Kernel::HLERequestContext& ctx); | 149 | void SetLayerScalingMode(Kernel::HLERequestContext& ctx); |
| 143 | void OpenLayer(Kernel::HLERequestContext& ctx); | 150 | void OpenLayer(Kernel::HLERequestContext& ctx); |
| 151 | void CreateStrayLayer(Kernel::HLERequestContext& ctx); | ||
| 152 | void DestroyStrayLayer(Kernel::HLERequestContext& ctx); | ||
| 144 | void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx); | 153 | void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx); |
| 145 | 154 | ||
| 146 | std::shared_ptr<NVFlinger> nv_flinger; | 155 | std::shared_ptr<NVFlinger> nv_flinger; |