summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/kernel/k_synchronization_object.cpp3
-rw-r--r--src/core/hle/kernel/k_thread.cpp8
-rw-r--r--src/core/hle/kernel/k_thread.h3
-rw-r--r--src/core/hle/kernel/svc/svc_ipc.cpp7
-rw-r--r--src/core/hle/kernel/svc/svc_synchronization.cpp10
-rw-r--r--src/core/hle/kernel/svc/svc_thread.cpp2
-rw-r--r--src/core/hle/service/audio/audin_u.cpp16
-rw-r--r--src/core/hle/service/audio/audout_u.cpp15
-rw-r--r--src/core/hle/service/audio/audren_u.cpp22
-rw-r--r--src/core/hle/service/audio/audren_u.h1
-rw-r--r--src/core/hle/service/audio/hwopus.cpp9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdevice.h6
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp6
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp31
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h30
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp19
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h21
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp32
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h38
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp59
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h36
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp6
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp15
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h12
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h10
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp6
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp20
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.h20
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp8
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h8
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.cpp24
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.h3
-rw-r--r--src/core/hle/service/nvnflinger/parcel.h7
37 files changed, 270 insertions, 275 deletions
diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp
index b7da3eee7..3e5b735b1 100644
--- a/src/core/hle/kernel/k_synchronization_object.cpp
+++ b/src/core/hle/kernel/k_synchronization_object.cpp
@@ -3,6 +3,7 @@
3 3
4#include "common/assert.h" 4#include "common/assert.h"
5#include "common/common_types.h" 5#include "common/common_types.h"
6#include "common/scratch_buffer.h"
6#include "core/hle/kernel/k_scheduler.h" 7#include "core/hle/kernel/k_scheduler.h"
7#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" 8#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
8#include "core/hle/kernel/k_synchronization_object.h" 9#include "core/hle/kernel/k_synchronization_object.h"
@@ -75,7 +76,7 @@ Result KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index,
75 KSynchronizationObject** objects, const s32 num_objects, 76 KSynchronizationObject** objects, const s32 num_objects,
76 s64 timeout) { 77 s64 timeout) {
77 // Allocate space on stack for thread nodes. 78 // Allocate space on stack for thread nodes.
78 std::vector<ThreadListNode> thread_nodes(num_objects); 79 std::array<ThreadListNode, Svc::ArgumentHandleCountMax> thread_nodes;
79 80
80 // Prepare for wait. 81 // Prepare for wait.
81 KThread* thread = GetCurrentThreadPointer(kernel); 82 KThread* thread = GetCurrentThreadPointer(kernel);
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 908811e2c..adb6ec581 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -909,7 +909,7 @@ Result KThread::SetActivity(Svc::ThreadActivity activity) {
909 R_SUCCEED(); 909 R_SUCCEED();
910} 910}
911 911
912Result KThread::GetThreadContext3(std::vector<u8>& out) { 912Result KThread::GetThreadContext3(Common::ScratchBuffer<u8>& out) {
913 // Lock ourselves. 913 // Lock ourselves.
914 KScopedLightLock lk{m_activity_pause_lock}; 914 KScopedLightLock lk{m_activity_pause_lock};
915 915
@@ -927,15 +927,13 @@ Result KThread::GetThreadContext3(std::vector<u8>& out) {
927 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits. 927 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
928 auto context = GetContext64(); 928 auto context = GetContext64();
929 context.pstate &= 0xFF0FFE20; 929 context.pstate &= 0xFF0FFE20;
930 930 out.resize_destructive(sizeof(context));
931 out.resize(sizeof(context));
932 std::memcpy(out.data(), std::addressof(context), sizeof(context)); 931 std::memcpy(out.data(), std::addressof(context), sizeof(context));
933 } else { 932 } else {
934 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits. 933 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
935 auto context = GetContext32(); 934 auto context = GetContext32();
936 context.cpsr &= 0xFF0FFE20; 935 context.cpsr &= 0xFF0FFE20;
937 936 out.resize_destructive(sizeof(context));
938 out.resize(sizeof(context));
939 std::memcpy(out.data(), std::addressof(context), sizeof(context)); 937 std::memcpy(out.data(), std::addressof(context), sizeof(context));
940 } 938 }
941 } 939 }
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 37fe5db77..dd662b3f8 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -15,6 +15,7 @@
15#include "common/intrusive_list.h" 15#include "common/intrusive_list.h"
16 16
17#include "common/intrusive_red_black_tree.h" 17#include "common/intrusive_red_black_tree.h"
18#include "common/scratch_buffer.h"
18#include "common/spin_lock.h" 19#include "common/spin_lock.h"
19#include "core/arm/arm_interface.h" 20#include "core/arm/arm_interface.h"
20#include "core/hle/kernel/k_affinity_mask.h" 21#include "core/hle/kernel/k_affinity_mask.h"
@@ -567,7 +568,7 @@ public:
567 568
568 void RemoveWaiter(KThread* thread); 569 void RemoveWaiter(KThread* thread);
569 570
570 Result GetThreadContext3(std::vector<u8>& out); 571 Result GetThreadContext3(Common::ScratchBuffer<u8>& out);
571 572
572 KThread* RemoveUserWaiterByKey(bool* out_has_waiters, KProcessAddress key) { 573 KThread* RemoveUserWaiterByKey(bool* out_has_waiters, KProcessAddress key) {
573 return this->RemoveWaiterByKey(out_has_waiters, key, false); 574 return this->RemoveWaiterByKey(out_has_waiters, key, false);
diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp
index ea03068aa..60247df2e 100644
--- a/src/core/hle/kernel/svc/svc_ipc.cpp
+++ b/src/core/hle/kernel/svc/svc_ipc.cpp
@@ -2,6 +2,7 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/scope_exit.h" 4#include "common/scope_exit.h"
5#include "common/scratch_buffer.h"
5#include "core/core.h" 6#include "core/core.h"
6#include "core/hle/kernel/k_client_session.h" 7#include "core/hle/kernel/k_client_session.h"
7#include "core/hle/kernel/k_process.h" 8#include "core/hle/kernel/k_process.h"
@@ -45,11 +46,11 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad
45 handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), 46 handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)),
46 ResultInvalidPointer); 47 ResultInvalidPointer);
47 48
48 std::vector<Handle> handles(num_handles); 49 std::array<Handle, Svc::ArgumentHandleCountMax> handles;
49 GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles); 50 GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles);
50 51
51 // Convert handle list to object table. 52 // Convert handle list to object table.
52 std::vector<KSynchronizationObject*> objs(num_handles); 53 std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> objs;
53 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(), 54 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(),
54 num_handles), 55 num_handles),
55 ResultInvalidHandle); 56 ResultInvalidHandle);
@@ -80,7 +81,7 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad
80 // Wait for an object. 81 // Wait for an object.
81 s32 index; 82 s32 index;
82 Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs.data(), 83 Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs.data(),
83 static_cast<s32>(objs.size()), timeout_ns); 84 num_handles, timeout_ns);
84 if (result == ResultTimedOut) { 85 if (result == ResultTimedOut) {
85 R_RETURN(result); 86 R_RETURN(result);
86 } 87 }
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp
index 04d65f0bd..53df5bcd8 100644
--- a/src/core/hle/kernel/svc/svc_synchronization.cpp
+++ b/src/core/hle/kernel/svc/svc_synchronization.cpp
@@ -2,6 +2,7 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/scope_exit.h" 4#include "common/scope_exit.h"
5#include "common/scratch_buffer.h"
5#include "core/core.h" 6#include "core/core.h"
6#include "core/hle/kernel/k_process.h" 7#include "core/hle/kernel/k_process.h"
7#include "core/hle/kernel/k_readable_event.h" 8#include "core/hle/kernel/k_readable_event.h"
@@ -54,7 +55,7 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons
54 // Get the synchronization context. 55 // Get the synchronization context.
55 auto& kernel = system.Kernel(); 56 auto& kernel = system.Kernel();
56 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); 57 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
57 std::vector<KSynchronizationObject*> objs(num_handles); 58 std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> objs;
58 59
59 // Copy user handles. 60 // Copy user handles.
60 if (num_handles > 0) { 61 if (num_handles > 0) {
@@ -72,8 +73,8 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons
72 }); 73 });
73 74
74 // Wait on the objects. 75 // Wait on the objects.
75 Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(), 76 Result res =
76 static_cast<s32>(objs.size()), timeout_ns); 77 KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout_ns);
77 78
78 R_SUCCEED_IF(res == ResultSessionClosed); 79 R_SUCCEED_IF(res == ResultSessionClosed);
79 R_RETURN(res); 80 R_RETURN(res);
@@ -87,8 +88,7 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha
87 88
88 // Ensure number of handles is valid. 89 // Ensure number of handles is valid.
89 R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange); 90 R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange);
90 91 std::array<Handle, Svc::ArgumentHandleCountMax> handles;
91 std::vector<Handle> handles(num_handles);
92 if (num_handles > 0) { 92 if (num_handles > 0) {
93 GetCurrentMemory(system.Kernel()) 93 GetCurrentMemory(system.Kernel())
94 .ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle)); 94 .ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle));
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp
index 37b54079c..36b94e6bf 100644
--- a/src/core/hle/kernel/svc/svc_thread.cpp
+++ b/src/core/hle/kernel/svc/svc_thread.cpp
@@ -174,7 +174,7 @@ Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_ha
174 } 174 }
175 175
176 // Get the thread context. 176 // Get the thread context.
177 std::vector<u8> context; 177 static thread_local Common::ScratchBuffer<u8> context;
178 R_TRY(thread->GetThreadContext3(context)); 178 R_TRY(thread->GetThreadContext3(context));
179 179
180 // Copy the thread context to user space. 180 // Copy the thread context to user space.
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp
index f0640c64f..c8d574993 100644
--- a/src/core/hle/service/audio/audin_u.cpp
+++ b/src/core/hle/service/audio/audin_u.cpp
@@ -5,6 +5,7 @@
5#include "audio_core/renderer/audio_device.h" 5#include "audio_core/renderer/audio_device.h"
6#include "common/common_funcs.h" 6#include "common/common_funcs.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "common/settings.h"
8#include "common/string_util.h" 9#include "common/string_util.h"
9#include "core/core.h" 10#include "core/core.h"
10#include "core/hle/kernel/k_event.h" 11#include "core/hle/kernel/k_event.h"
@@ -123,19 +124,13 @@ private:
123 124
124 void GetReleasedAudioInBuffer(HLERequestContext& ctx) { 125 void GetReleasedAudioInBuffer(HLERequestContext& ctx) {
125 const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); 126 const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>();
126 std::vector<u64> released_buffers(write_buffer_size); 127 tmp_buffer.resize_destructive(write_buffer_size);
128 tmp_buffer[0] = 0;
127 129
128 const auto count = impl->GetReleasedBuffers(released_buffers); 130 const auto count = impl->GetReleasedBuffers(tmp_buffer);
129 131
130 [[maybe_unused]] std::string tags{}; 132 ctx.WriteBuffer(tmp_buffer);
131 for (u32 i = 0; i < count; i++) {
132 tags += fmt::format("{:08X}, ", released_buffers[i]);
133 }
134 [[maybe_unused]] auto sessionid{impl->GetSystem().GetSessionId()};
135 LOG_TRACE(Service_Audio, "called. Session {} released {} buffers: {}", sessionid, count,
136 tags);
137 133
138 ctx.WriteBuffer(released_buffers);
139 IPC::ResponseBuilder rb{ctx, 3}; 134 IPC::ResponseBuilder rb{ctx, 3};
140 rb.Push(ResultSuccess); 135 rb.Push(ResultSuccess);
141 rb.Push(count); 136 rb.Push(count);
@@ -200,6 +195,7 @@ private:
200 KernelHelpers::ServiceContext service_context; 195 KernelHelpers::ServiceContext service_context;
201 Kernel::KEvent* event; 196 Kernel::KEvent* event;
202 std::shared_ptr<AudioCore::AudioIn::In> impl; 197 std::shared_ptr<AudioCore::AudioIn::In> impl;
198 Common::ScratchBuffer<u64> tmp_buffer;
203}; 199};
204 200
205AudInU::AudInU(Core::System& system_) 201AudInU::AudInU(Core::System& system_)
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 3e62fa4fc..032c8c11f 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -123,19 +123,13 @@ private:
123 123
124 void GetReleasedAudioOutBuffers(HLERequestContext& ctx) { 124 void GetReleasedAudioOutBuffers(HLERequestContext& ctx) {
125 const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>(); 125 const auto write_buffer_size = ctx.GetWriteBufferNumElements<u64>();
126 std::vector<u64> released_buffers(write_buffer_size); 126 tmp_buffer.resize_destructive(write_buffer_size);
127 tmp_buffer[0] = 0;
127 128
128 const auto count = impl->GetReleasedBuffers(released_buffers); 129 const auto count = impl->GetReleasedBuffers(tmp_buffer);
129 130
130 [[maybe_unused]] std::string tags{}; 131 ctx.WriteBuffer(tmp_buffer);
131 for (u32 i = 0; i < count; i++) {
132 tags += fmt::format("{:08X}, ", released_buffers[i]);
133 }
134 [[maybe_unused]] const auto sessionid{impl->GetSystem().GetSessionId()};
135 LOG_TRACE(Service_Audio, "called. Session {} released {} buffers: {}", sessionid, count,
136 tags);
137 132
138 ctx.WriteBuffer(released_buffers);
139 IPC::ResponseBuilder rb{ctx, 3}; 133 IPC::ResponseBuilder rb{ctx, 3};
140 rb.Push(ResultSuccess); 134 rb.Push(ResultSuccess);
141 rb.Push(count); 135 rb.Push(count);
@@ -211,6 +205,7 @@ private:
211 KernelHelpers::ServiceContext service_context; 205 KernelHelpers::ServiceContext service_context;
212 Kernel::KEvent* event; 206 Kernel::KEvent* event;
213 std::shared_ptr<AudioCore::AudioOut::Out> impl; 207 std::shared_ptr<AudioCore::AudioOut::Out> impl;
208 Common::ScratchBuffer<u64> tmp_buffer;
214}; 209};
215 210
216AudOutU::AudOutU(Core::System& system_) 211AudOutU::AudOutU(Core::System& system_)
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 7086d4750..12845c23a 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -116,28 +116,26 @@ private:
116 // These buffers are written manually to avoid an issue with WriteBuffer throwing errors for 116 // These buffers are written manually to avoid an issue with WriteBuffer throwing errors for
117 // checking size 0. Performance size is 0 for most games. 117 // checking size 0. Performance size is 0 for most games.
118 118
119 std::vector<u8> output{};
120 std::vector<u8> performance{};
121 auto is_buffer_b{ctx.BufferDescriptorB()[0].Size() != 0}; 119 auto is_buffer_b{ctx.BufferDescriptorB()[0].Size() != 0};
122 if (is_buffer_b) { 120 if (is_buffer_b) {
123 const auto buffersB{ctx.BufferDescriptorB()}; 121 const auto buffersB{ctx.BufferDescriptorB()};
124 output.resize(buffersB[0].Size(), 0); 122 tmp_output.resize_destructive(buffersB[0].Size());
125 performance.resize(buffersB[1].Size(), 0); 123 tmp_performance.resize_destructive(buffersB[1].Size());
126 } else { 124 } else {
127 const auto buffersC{ctx.BufferDescriptorC()}; 125 const auto buffersC{ctx.BufferDescriptorC()};
128 output.resize(buffersC[0].Size(), 0); 126 tmp_output.resize_destructive(buffersC[0].Size());
129 performance.resize(buffersC[1].Size(), 0); 127 tmp_performance.resize_destructive(buffersC[1].Size());
130 } 128 }
131 129
132 auto result = impl->RequestUpdate(input, performance, output); 130 auto result = impl->RequestUpdate(input, tmp_performance, tmp_output);
133 131
134 if (result.IsSuccess()) { 132 if (result.IsSuccess()) {
135 if (is_buffer_b) { 133 if (is_buffer_b) {
136 ctx.WriteBufferB(output.data(), output.size(), 0); 134 ctx.WriteBufferB(tmp_output.data(), tmp_output.size(), 0);
137 ctx.WriteBufferB(performance.data(), performance.size(), 1); 135 ctx.WriteBufferB(tmp_performance.data(), tmp_performance.size(), 1);
138 } else { 136 } else {
139 ctx.WriteBufferC(output.data(), output.size(), 0); 137 ctx.WriteBufferC(tmp_output.data(), tmp_output.size(), 0);
140 ctx.WriteBufferC(performance.data(), performance.size(), 1); 138 ctx.WriteBufferC(tmp_performance.data(), tmp_performance.size(), 1);
141 } 139 }
142 } else { 140 } else {
143 LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", result.description); 141 LOG_ERROR(Service_Audio, "RequestUpdate failed error 0x{:02X}!", result.description);
@@ -235,6 +233,8 @@ private:
235 Kernel::KEvent* rendered_event; 233 Kernel::KEvent* rendered_event;
236 Manager& manager; 234 Manager& manager;
237 std::unique_ptr<Renderer> impl; 235 std::unique_ptr<Renderer> impl;
236 Common::ScratchBuffer<u8> tmp_output;
237 Common::ScratchBuffer<u8> tmp_performance;
238}; 238};
239 239
240class IAudioDevice final : public ServiceFramework<IAudioDevice> { 240class IAudioDevice final : public ServiceFramework<IAudioDevice> {
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h
index 24ce37e87..d8e9c8719 100644
--- a/src/core/hle/service/audio/audren_u.h
+++ b/src/core/hle/service/audio/audren_u.h
@@ -4,6 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include "audio_core/audio_render_manager.h" 6#include "audio_core/audio_render_manager.h"
7#include "common/scratch_buffer.h"
7#include "core/hle/service/kernel_helpers.h" 8#include "core/hle/service/kernel_helpers.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9 10
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index 451ac224a..c835f6cb7 100644
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -68,13 +68,13 @@ private:
68 ExtraBehavior extra_behavior) { 68 ExtraBehavior extra_behavior) {
69 u32 consumed = 0; 69 u32 consumed = 0;
70 u32 sample_count = 0; 70 u32 sample_count = 0;
71 std::vector<opus_int16> samples(ctx.GetWriteBufferNumElements<opus_int16>()); 71 tmp_samples.resize_destructive(ctx.GetWriteBufferNumElements<opus_int16>());
72 72
73 if (extra_behavior == ExtraBehavior::ResetContext) { 73 if (extra_behavior == ExtraBehavior::ResetContext) {
74 ResetDecoderContext(); 74 ResetDecoderContext();
75 } 75 }
76 76
77 if (!DecodeOpusData(consumed, sample_count, ctx.ReadBuffer(), samples, performance)) { 77 if (!DecodeOpusData(consumed, sample_count, ctx.ReadBuffer(), tmp_samples, performance)) {
78 LOG_ERROR(Audio, "Failed to decode opus data"); 78 LOG_ERROR(Audio, "Failed to decode opus data");
79 IPC::ResponseBuilder rb{ctx, 2}; 79 IPC::ResponseBuilder rb{ctx, 2};
80 // TODO(ogniK): Use correct error code 80 // TODO(ogniK): Use correct error code
@@ -90,11 +90,11 @@ private:
90 if (performance) { 90 if (performance) {
91 rb.Push<u64>(*performance); 91 rb.Push<u64>(*performance);
92 } 92 }
93 ctx.WriteBuffer(samples); 93 ctx.WriteBuffer(tmp_samples);
94 } 94 }
95 95
96 bool DecodeOpusData(u32& consumed, u32& sample_count, std::span<const u8> input, 96 bool DecodeOpusData(u32& consumed, u32& sample_count, std::span<const u8> input,
97 std::vector<opus_int16>& output, u64* out_performance_time) const { 97 std::span<opus_int16> output, u64* out_performance_time) const {
98 const auto start_time = std::chrono::steady_clock::now(); 98 const auto start_time = std::chrono::steady_clock::now();
99 const std::size_t raw_output_sz = output.size() * sizeof(opus_int16); 99 const std::size_t raw_output_sz = output.size() * sizeof(opus_int16);
100 if (sizeof(OpusPacketHeader) > input.size()) { 100 if (sizeof(OpusPacketHeader) > input.size()) {
@@ -154,6 +154,7 @@ private:
154 OpusDecoderPtr decoder; 154 OpusDecoderPtr decoder;
155 u32 sample_rate; 155 u32 sample_rate;
156 u32 channel_count; 156 u32 channel_count;
157 Common::ScratchBuffer<opus_int16> tmp_samples;
157}; 158};
158 159
159class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> { 160class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> {
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h
index ab1f30f9e..a04538d5d 100644
--- a/src/core/hle/service/nvdrv/devices/nvdevice.h
+++ b/src/core/hle/service/nvdrv/devices/nvdevice.h
@@ -34,7 +34,7 @@ public:
34 * @returns The result code of the ioctl. 34 * @returns The result code of the ioctl.
35 */ 35 */
36 virtual NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 36 virtual NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
37 std::vector<u8>& output) = 0; 37 std::span<u8> output) = 0;
38 38
39 /** 39 /**
40 * Handles an ioctl2 request. 40 * Handles an ioctl2 request.
@@ -45,7 +45,7 @@ public:
45 * @returns The result code of the ioctl. 45 * @returns The result code of the ioctl.
46 */ 46 */
47 virtual NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 47 virtual NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
48 std::span<const u8> inline_input, std::vector<u8>& output) = 0; 48 std::span<const u8> inline_input, std::span<u8> output) = 0;
49 49
50 /** 50 /**
51 * Handles an ioctl3 request. 51 * Handles an ioctl3 request.
@@ -56,7 +56,7 @@ public:
56 * @returns The result code of the ioctl. 56 * @returns The result code of the ioctl.
57 */ 57 */
58 virtual NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, 58 virtual NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
59 std::vector<u8>& output, std::vector<u8>& inline_output) = 0; 59 std::span<u8> output, std::span<u8> inline_output) = 0;
60 60
61 /** 61 /**
62 * Called once a device is opened 62 * Called once a device is opened
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index 0fe242e9d..05a43d8dc 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -18,19 +18,19 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system_, NvCore::Container& core)
18nvdisp_disp0::~nvdisp_disp0() = default; 18nvdisp_disp0::~nvdisp_disp0() = default;
19 19
20NvResult nvdisp_disp0::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 20NvResult nvdisp_disp0::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
21 std::vector<u8>& output) { 21 std::span<u8> output) {
22 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 22 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
23 return NvResult::NotImplemented; 23 return NvResult::NotImplemented;
24} 24}
25 25
26NvResult nvdisp_disp0::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 26NvResult nvdisp_disp0::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
27 std::span<const u8> inline_input, std::vector<u8>& output) { 27 std::span<const u8> inline_input, std::span<u8> output) {
28 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 28 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
29 return NvResult::NotImplemented; 29 return NvResult::NotImplemented;
30} 30}
31 31
32NvResult nvdisp_disp0::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, 32NvResult nvdisp_disp0::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
33 std::vector<u8>& output, std::vector<u8>& inline_output) { 33 std::span<u8> output, std::span<u8> inline_output) {
34 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 34 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
35 return NvResult::NotImplemented; 35 return NvResult::NotImplemented;
36} 36}
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
index bcd0e3ed5..daee05fe8 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
@@ -26,11 +26,11 @@ public:
26 ~nvdisp_disp0() override; 26 ~nvdisp_disp0() override;
27 27
28 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 28 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
29 std::vector<u8>& output) override; 29 std::span<u8> output) override;
30 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 30 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
31 std::span<const u8> inline_input, std::vector<u8>& output) override; 31 std::span<const u8> inline_input, std::span<u8> output) override;
32 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, 32 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
33 std::vector<u8>& inline_output) override; 33 std::span<u8> inline_output) override;
34 34
35 void OnOpen(DeviceFD fd) override; 35 void OnOpen(DeviceFD fd) override;
36 void OnClose(DeviceFD fd) override; 36 void OnClose(DeviceFD fd) override;
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 681bd0867..07e570a9f 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -28,7 +28,7 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system_, Module& module_, NvCore::Con
28nvhost_as_gpu::~nvhost_as_gpu() = default; 28nvhost_as_gpu::~nvhost_as_gpu() = default;
29 29
30NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 30NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
31 std::vector<u8>& output) { 31 std::span<u8> output) {
32 switch (command.group) { 32 switch (command.group) {
33 case 'A': 33 case 'A':
34 switch (command.cmd) { 34 switch (command.cmd) {
@@ -61,13 +61,13 @@ NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> i
61} 61}
62 62
63NvResult nvhost_as_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 63NvResult nvhost_as_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
64 std::span<const u8> inline_input, std::vector<u8>& output) { 64 std::span<const u8> inline_input, std::span<u8> output) {
65 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 65 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
66 return NvResult::NotImplemented; 66 return NvResult::NotImplemented;
67} 67}
68 68
69NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, 69NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
70 std::vector<u8>& output, std::vector<u8>& inline_output) { 70 std::span<u8> output, std::span<u8> inline_output) {
71 switch (command.group) { 71 switch (command.group) {
72 case 'A': 72 case 'A':
73 switch (command.cmd) { 73 switch (command.cmd) {
@@ -87,7 +87,7 @@ NvResult nvhost_as_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> i
87void nvhost_as_gpu::OnOpen(DeviceFD fd) {} 87void nvhost_as_gpu::OnOpen(DeviceFD fd) {}
88void nvhost_as_gpu::OnClose(DeviceFD fd) {} 88void nvhost_as_gpu::OnClose(DeviceFD fd) {}
89 89
90NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::vector<u8>& output) { 90NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::span<u8> output) {
91 IoctlAllocAsEx params{}; 91 IoctlAllocAsEx params{};
92 std::memcpy(&params, input.data(), input.size()); 92 std::memcpy(&params, input.data(), input.size());
93 93
@@ -141,7 +141,7 @@ NvResult nvhost_as_gpu::AllocAsEx(std::span<const u8> input, std::vector<u8>& ou
141 return NvResult::Success; 141 return NvResult::Success;
142} 142}
143 143
144NvResult nvhost_as_gpu::AllocateSpace(std::span<const u8> input, std::vector<u8>& output) { 144NvResult nvhost_as_gpu::AllocateSpace(std::span<const u8> input, std::span<u8> output) {
145 IoctlAllocSpace params{}; 145 IoctlAllocSpace params{};
146 std::memcpy(&params, input.data(), input.size()); 146 std::memcpy(&params, input.data(), input.size());
147 147
@@ -220,7 +220,7 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) {
220 mapping_map.erase(offset); 220 mapping_map.erase(offset);
221} 221}
222 222
223NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::vector<u8>& output) { 223NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::span<u8> output) {
224 IoctlFreeSpace params{}; 224 IoctlFreeSpace params{};
225 std::memcpy(&params, input.data(), input.size()); 225 std::memcpy(&params, input.data(), input.size());
226 226
@@ -266,15 +266,14 @@ NvResult nvhost_as_gpu::FreeSpace(std::span<const u8> input, std::vector<u8>& ou
266 return NvResult::Success; 266 return NvResult::Success;
267} 267}
268 268
269NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::vector<u8>& output) { 269NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::span<u8> output) {
270 const auto num_entries = input.size() / sizeof(IoctlRemapEntry); 270 const auto num_entries = input.size() / sizeof(IoctlRemapEntry);
271 271
272 LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", num_entries); 272 LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", num_entries);
273 273
274 std::vector<IoctlRemapEntry> entries(num_entries);
275 std::memcpy(entries.data(), input.data(), input.size());
276
277 std::scoped_lock lock(mutex); 274 std::scoped_lock lock(mutex);
275 entries.resize_destructive(num_entries);
276 std::memcpy(entries.data(), input.data(), input.size());
278 277
279 if (!vm.initialised) { 278 if (!vm.initialised) {
280 return NvResult::BadValue; 279 return NvResult::BadValue;
@@ -320,7 +319,7 @@ NvResult nvhost_as_gpu::Remap(std::span<const u8> input, std::vector<u8>& output
320 return NvResult::Success; 319 return NvResult::Success;
321} 320}
322 321
323NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::vector<u8>& output) { 322NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::span<u8> output) {
324 IoctlMapBufferEx params{}; 323 IoctlMapBufferEx params{};
325 std::memcpy(&params, input.data(), input.size()); 324 std::memcpy(&params, input.data(), input.size());
326 325
@@ -424,7 +423,7 @@ NvResult nvhost_as_gpu::MapBufferEx(std::span<const u8> input, std::vector<u8>&
424 return NvResult::Success; 423 return NvResult::Success;
425} 424}
426 425
427NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::vector<u8>& output) { 426NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::span<u8> output) {
428 IoctlUnmapBuffer params{}; 427 IoctlUnmapBuffer params{};
429 std::memcpy(&params, input.data(), input.size()); 428 std::memcpy(&params, input.data(), input.size());
430 429
@@ -463,7 +462,7 @@ NvResult nvhost_as_gpu::UnmapBuffer(std::span<const u8> input, std::vector<u8>&
463 return NvResult::Success; 462 return NvResult::Success;
464} 463}
465 464
466NvResult nvhost_as_gpu::BindChannel(std::span<const u8> input, std::vector<u8>& output) { 465NvResult nvhost_as_gpu::BindChannel(std::span<const u8> input, std::span<u8> output) {
467 IoctlBindChannel params{}; 466 IoctlBindChannel params{};
468 std::memcpy(&params, input.data(), input.size()); 467 std::memcpy(&params, input.data(), input.size());
469 LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); 468 LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd);
@@ -492,7 +491,7 @@ void nvhost_as_gpu::GetVARegionsImpl(IoctlGetVaRegions& params) {
492 }; 491 };
493} 492}
494 493
495NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::vector<u8>& output) { 494NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> output) {
496 IoctlGetVaRegions params{}; 495 IoctlGetVaRegions params{};
497 std::memcpy(&params, input.data(), input.size()); 496 std::memcpy(&params, input.data(), input.size());
498 497
@@ -511,8 +510,8 @@ NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::vector<u8>&
511 return NvResult::Success; 510 return NvResult::Success;
512} 511}
513 512
514NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::vector<u8>& output, 513NvResult nvhost_as_gpu::GetVARegions(std::span<const u8> input, std::span<u8> output,
515 std::vector<u8>& inline_output) { 514 std::span<u8> inline_output) {
516 IoctlGetVaRegions params{}; 515 IoctlGetVaRegions params{};
517 std::memcpy(&params, input.data(), input.size()); 516 std::memcpy(&params, input.data(), input.size());
518 517
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 1aba8d579..2af3e1260 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
@@ -15,6 +15,7 @@
15#include "common/address_space.h" 15#include "common/address_space.h"
16#include "common/common_funcs.h" 16#include "common/common_funcs.h"
17#include "common/common_types.h" 17#include "common/common_types.h"
18#include "common/scratch_buffer.h"
18#include "common/swap.h" 19#include "common/swap.h"
19#include "core/hle/service/nvdrv/core/nvmap.h" 20#include "core/hle/service/nvdrv/core/nvmap.h"
20#include "core/hle/service/nvdrv/devices/nvdevice.h" 21#include "core/hle/service/nvdrv/devices/nvdevice.h"
@@ -48,11 +49,11 @@ public:
48 ~nvhost_as_gpu() override; 49 ~nvhost_as_gpu() override;
49 50
50 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 51 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
51 std::vector<u8>& output) override; 52 std::span<u8> output) override;
52 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 53 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
53 std::span<const u8> inline_input, std::vector<u8>& output) override; 54 std::span<const u8> inline_input, std::span<u8> output) override;
54 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, 55 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
55 std::vector<u8>& inline_output) override; 56 std::span<u8> inline_output) override;
56 57
57 void OnOpen(DeviceFD fd) override; 58 void OnOpen(DeviceFD fd) override;
58 void OnClose(DeviceFD fd) override; 59 void OnClose(DeviceFD fd) override;
@@ -138,18 +139,18 @@ private:
138 static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2, 139 static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2,
139 "IoctlGetVaRegions is incorrect size"); 140 "IoctlGetVaRegions is incorrect size");
140 141
141 NvResult AllocAsEx(std::span<const u8> input, std::vector<u8>& output); 142 NvResult AllocAsEx(std::span<const u8> input, std::span<u8> output);
142 NvResult AllocateSpace(std::span<const u8> input, std::vector<u8>& output); 143 NvResult AllocateSpace(std::span<const u8> input, std::span<u8> output);
143 NvResult Remap(std::span<const u8> input, std::vector<u8>& output); 144 NvResult Remap(std::span<const u8> input, std::span<u8> output);
144 NvResult MapBufferEx(std::span<const u8> input, std::vector<u8>& output); 145 NvResult MapBufferEx(std::span<const u8> input, std::span<u8> output);
145 NvResult UnmapBuffer(std::span<const u8> input, std::vector<u8>& output); 146 NvResult UnmapBuffer(std::span<const u8> input, std::span<u8> output);
146 NvResult FreeSpace(std::span<const u8> input, std::vector<u8>& output); 147 NvResult FreeSpace(std::span<const u8> input, std::span<u8> output);
147 NvResult BindChannel(std::span<const u8> input, std::vector<u8>& output); 148 NvResult BindChannel(std::span<const u8> input, std::span<u8> output);
148 149
149 void GetVARegionsImpl(IoctlGetVaRegions& params); 150 void GetVARegionsImpl(IoctlGetVaRegions& params);
150 NvResult GetVARegions(std::span<const u8> input, std::vector<u8>& output); 151 NvResult GetVARegions(std::span<const u8> input, std::span<u8> output);
151 NvResult GetVARegions(std::span<const u8> input, std::vector<u8>& output, 152 NvResult GetVARegions(std::span<const u8> input, std::span<u8> output,
152 std::vector<u8>& inline_output); 153 std::span<u8> inline_output);
153 154
154 void FreeMappingLocked(u64 offset); 155 void FreeMappingLocked(u64 offset);
155 156
@@ -212,6 +213,7 @@ private:
212 bool initialised{}; 213 bool initialised{};
213 } vm; 214 } vm;
214 std::shared_ptr<Tegra::MemoryManager> gmmu; 215 std::shared_ptr<Tegra::MemoryManager> gmmu;
216 Common::ScratchBuffer<IoctlRemapEntry> entries;
215 217
216 // s32 channel{}; 218 // s32 channel{};
217 // u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE}; 219 // u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE};
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index e12025560..4d55554b4 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -35,7 +35,7 @@ nvhost_ctrl::~nvhost_ctrl() {
35} 35}
36 36
37NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 37NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
38 std::vector<u8>& output) { 38 std::span<u8> output) {
39 switch (command.group) { 39 switch (command.group) {
40 case 0x0: 40 case 0x0:
41 switch (command.cmd) { 41 switch (command.cmd) {
@@ -64,13 +64,13 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inp
64} 64}
65 65
66NvResult nvhost_ctrl::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 66NvResult nvhost_ctrl::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
67 std::span<const u8> inline_input, std::vector<u8>& output) { 67 std::span<const u8> inline_input, std::span<u8> output) {
68 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 68 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
69 return NvResult::NotImplemented; 69 return NvResult::NotImplemented;
70} 70}
71 71
72NvResult nvhost_ctrl::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, 72NvResult nvhost_ctrl::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
73 std::vector<u8>& output, std::vector<u8>& inline_outpu) { 73 std::span<u8> output, std::span<u8> inline_outpu) {
74 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 74 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
75 return NvResult::NotImplemented; 75 return NvResult::NotImplemented;
76} 76}
@@ -79,7 +79,7 @@ void nvhost_ctrl::OnOpen(DeviceFD fd) {}
79 79
80void nvhost_ctrl::OnClose(DeviceFD fd) {} 80void nvhost_ctrl::OnClose(DeviceFD fd) {}
81 81
82NvResult nvhost_ctrl::NvOsGetConfigU32(std::span<const u8> input, std::vector<u8>& output) { 82NvResult nvhost_ctrl::NvOsGetConfigU32(std::span<const u8> input, std::span<u8> output) {
83 IocGetConfigParams params{}; 83 IocGetConfigParams params{};
84 std::memcpy(&params, input.data(), sizeof(params)); 84 std::memcpy(&params, input.data(), sizeof(params));
85 LOG_TRACE(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(), 85 LOG_TRACE(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(),
@@ -87,7 +87,7 @@ NvResult nvhost_ctrl::NvOsGetConfigU32(std::span<const u8> input, std::vector<u8
87 return NvResult::ConfigVarNotFound; // Returns error on production mode 87 return NvResult::ConfigVarNotFound; // Returns error on production mode
88} 88}
89 89
90NvResult nvhost_ctrl::IocCtrlEventWait(std::span<const u8> input, std::vector<u8>& output, 90NvResult nvhost_ctrl::IocCtrlEventWait(std::span<const u8> input, std::span<u8> output,
91 bool is_allocation) { 91 bool is_allocation) {
92 IocCtrlEventWaitParams params{}; 92 IocCtrlEventWaitParams params{};
93 std::memcpy(&params, input.data(), sizeof(params)); 93 std::memcpy(&params, input.data(), sizeof(params));
@@ -231,7 +231,7 @@ NvResult nvhost_ctrl::FreeEvent(u32 slot) {
231 return NvResult::Success; 231 return NvResult::Success;
232} 232}
233 233
234NvResult nvhost_ctrl::IocCtrlEventRegister(std::span<const u8> input, std::vector<u8>& output) { 234NvResult nvhost_ctrl::IocCtrlEventRegister(std::span<const u8> input, std::span<u8> output) {
235 IocCtrlEventRegisterParams params{}; 235 IocCtrlEventRegisterParams params{};
236 std::memcpy(&params, input.data(), sizeof(params)); 236 std::memcpy(&params, input.data(), sizeof(params));
237 const u32 event_id = params.user_event_id; 237 const u32 event_id = params.user_event_id;
@@ -252,7 +252,7 @@ NvResult nvhost_ctrl::IocCtrlEventRegister(std::span<const u8> input, std::vecto
252 return NvResult::Success; 252 return NvResult::Success;
253} 253}
254 254
255NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span<const u8> input, std::vector<u8>& output) { 255NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span<const u8> input, std::span<u8> output) {
256 IocCtrlEventUnregisterParams params{}; 256 IocCtrlEventUnregisterParams params{};
257 std::memcpy(&params, input.data(), sizeof(params)); 257 std::memcpy(&params, input.data(), sizeof(params));
258 const u32 event_id = params.user_event_id & 0x00FF; 258 const u32 event_id = params.user_event_id & 0x00FF;
@@ -262,8 +262,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregister(std::span<const u8> input, std::vec
262 return FreeEvent(event_id); 262 return FreeEvent(event_id);
263} 263}
264 264
265NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span<const u8> input, 265NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span<const u8> input, std::span<u8> output) {
266 std::vector<u8>& output) {
267 IocCtrlEventUnregisterBatchParams params{}; 266 IocCtrlEventUnregisterBatchParams params{};
268 std::memcpy(&params, input.data(), sizeof(params)); 267 std::memcpy(&params, input.data(), sizeof(params));
269 u64 event_mask = params.user_events; 268 u64 event_mask = params.user_events;
@@ -281,7 +280,7 @@ NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(std::span<const u8> input,
281 return NvResult::Success; 280 return NvResult::Success;
282} 281}
283 282
284NvResult nvhost_ctrl::IocCtrlClearEventWait(std::span<const u8> input, std::vector<u8>& output) { 283NvResult nvhost_ctrl::IocCtrlClearEventWait(std::span<const u8> input, std::span<u8> output) {
285 IocCtrlEventClearParams params{}; 284 IocCtrlEventClearParams params{};
286 std::memcpy(&params, input.data(), sizeof(params)); 285 std::memcpy(&params, input.data(), sizeof(params));
287 286
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index dd2e7888a..2efed4862 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -26,11 +26,11 @@ public:
26 ~nvhost_ctrl() override; 26 ~nvhost_ctrl() override;
27 27
28 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 28 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
29 std::vector<u8>& output) override; 29 std::span<u8> output) override;
30 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 30 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
31 std::span<const u8> inline_input, std::vector<u8>& output) override; 31 std::span<const u8> inline_input, std::span<u8> output) override;
32 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, 32 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
33 std::vector<u8>& inline_output) override; 33 std::span<u8> inline_output) override;
34 34
35 void OnOpen(DeviceFD fd) override; 35 void OnOpen(DeviceFD fd) override;
36 void OnClose(DeviceFD fd) override; 36 void OnClose(DeviceFD fd) override;
@@ -186,13 +186,12 @@ private:
186 static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8, 186 static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8,
187 "IocCtrlEventKill is incorrect size"); 187 "IocCtrlEventKill is incorrect size");
188 188
189 NvResult NvOsGetConfigU32(std::span<const u8> input, std::vector<u8>& output); 189 NvResult NvOsGetConfigU32(std::span<const u8> input, std::span<u8> output);
190 NvResult IocCtrlEventWait(std::span<const u8> input, std::vector<u8>& output, 190 NvResult IocCtrlEventWait(std::span<const u8> input, std::span<u8> output, bool is_allocation);
191 bool is_allocation); 191 NvResult IocCtrlEventRegister(std::span<const u8> input, std::span<u8> output);
192 NvResult IocCtrlEventRegister(std::span<const u8> input, std::vector<u8>& output); 192 NvResult IocCtrlEventUnregister(std::span<const u8> input, std::span<u8> output);
193 NvResult IocCtrlEventUnregister(std::span<const u8> input, std::vector<u8>& output); 193 NvResult IocCtrlEventUnregisterBatch(std::span<const u8> input, std::span<u8> output);
194 NvResult IocCtrlEventUnregisterBatch(std::span<const u8> input, std::vector<u8>& output); 194 NvResult IocCtrlClearEventWait(std::span<const u8> input, std::span<u8> output);
195 NvResult IocCtrlClearEventWait(std::span<const u8> input, std::vector<u8>& output);
196 195
197 NvResult FreeEvent(u32 slot); 196 NvResult FreeEvent(u32 slot);
198 197
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index be3c083db..6081d92e9 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -22,7 +22,7 @@ nvhost_ctrl_gpu::~nvhost_ctrl_gpu() {
22} 22}
23 23
24NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 24NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
25 std::vector<u8>& output) { 25 std::span<u8> output) {
26 switch (command.group) { 26 switch (command.group) {
27 case 'G': 27 case 'G':
28 switch (command.cmd) { 28 switch (command.cmd) {
@@ -54,13 +54,13 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8>
54} 54}
55 55
56NvResult nvhost_ctrl_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 56NvResult nvhost_ctrl_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
57 std::span<const u8> inline_input, std::vector<u8>& output) { 57 std::span<const u8> inline_input, std::span<u8> output) {
58 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 58 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
59 return NvResult::NotImplemented; 59 return NvResult::NotImplemented;
60} 60}
61 61
62NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, 62NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
63 std::vector<u8>& output, std::vector<u8>& inline_output) { 63 std::span<u8> output, std::span<u8> inline_output) {
64 switch (command.group) { 64 switch (command.group) {
65 case 'G': 65 case 'G':
66 switch (command.cmd) { 66 switch (command.cmd) {
@@ -82,7 +82,7 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8>
82void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {} 82void nvhost_ctrl_gpu::OnOpen(DeviceFD fd) {}
83void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {} 83void nvhost_ctrl_gpu::OnClose(DeviceFD fd) {}
84 84
85NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::vector<u8>& output) { 85NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::span<u8> output) {
86 LOG_DEBUG(Service_NVDRV, "called"); 86 LOG_DEBUG(Service_NVDRV, "called");
87 IoctlCharacteristics params{}; 87 IoctlCharacteristics params{};
88 std::memcpy(&params, input.data(), input.size()); 88 std::memcpy(&params, input.data(), input.size());
@@ -127,8 +127,8 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::vec
127 return NvResult::Success; 127 return NvResult::Success;
128} 128}
129 129
130NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::vector<u8>& output, 130NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::span<u8> output,
131 std::vector<u8>& inline_output) { 131 std::span<u8> inline_output) {
132 LOG_DEBUG(Service_NVDRV, "called"); 132 LOG_DEBUG(Service_NVDRV, "called");
133 IoctlCharacteristics params{}; 133 IoctlCharacteristics params{};
134 std::memcpy(&params, input.data(), input.size()); 134 std::memcpy(&params, input.data(), input.size());
@@ -175,7 +175,7 @@ NvResult nvhost_ctrl_gpu::GetCharacteristics(std::span<const u8> input, std::vec
175 return NvResult::Success; 175 return NvResult::Success;
176} 176}
177 177
178NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::vector<u8>& output) { 178NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::span<u8> output) {
179 IoctlGpuGetTpcMasksArgs params{}; 179 IoctlGpuGetTpcMasksArgs params{};
180 std::memcpy(&params, input.data(), input.size()); 180 std::memcpy(&params, input.data(), input.size());
181 LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); 181 LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size);
@@ -186,8 +186,8 @@ NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::vector<u8>
186 return NvResult::Success; 186 return NvResult::Success;
187} 187}
188 188
189NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::vector<u8>& output, 189NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::span<u8> output,
190 std::vector<u8>& inline_output) { 190 std::span<u8> inline_output) {
191 IoctlGpuGetTpcMasksArgs params{}; 191 IoctlGpuGetTpcMasksArgs params{};
192 std::memcpy(&params, input.data(), input.size()); 192 std::memcpy(&params, input.data(), input.size());
193 LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size); 193 LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size=0x{:X}", params.mask_buffer_size);
@@ -199,7 +199,7 @@ NvResult nvhost_ctrl_gpu::GetTPCMasks(std::span<const u8> input, std::vector<u8>
199 return NvResult::Success; 199 return NvResult::Success;
200} 200}
201 201
202NvResult nvhost_ctrl_gpu::GetActiveSlotMask(std::span<const u8> input, std::vector<u8>& output) { 202NvResult nvhost_ctrl_gpu::GetActiveSlotMask(std::span<const u8> input, std::span<u8> output) {
203 LOG_DEBUG(Service_NVDRV, "called"); 203 LOG_DEBUG(Service_NVDRV, "called");
204 204
205 IoctlActiveSlotMask params{}; 205 IoctlActiveSlotMask params{};
@@ -212,7 +212,7 @@ NvResult nvhost_ctrl_gpu::GetActiveSlotMask(std::span<const u8> input, std::vect
212 return NvResult::Success; 212 return NvResult::Success;
213} 213}
214 214
215NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(std::span<const u8> input, std::vector<u8>& output) { 215NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(std::span<const u8> input, std::span<u8> output) {
216 LOG_DEBUG(Service_NVDRV, "called"); 216 LOG_DEBUG(Service_NVDRV, "called");
217 217
218 IoctlZcullGetCtxSize params{}; 218 IoctlZcullGetCtxSize params{};
@@ -224,7 +224,7 @@ NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(std::span<const u8> input, std::vector
224 return NvResult::Success; 224 return NvResult::Success;
225} 225}
226 226
227NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span<const u8> input, std::vector<u8>& output) { 227NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span<const u8> input, std::span<u8> output) {
228 LOG_DEBUG(Service_NVDRV, "called"); 228 LOG_DEBUG(Service_NVDRV, "called");
229 229
230 IoctlNvgpuGpuZcullGetInfoArgs params{}; 230 IoctlNvgpuGpuZcullGetInfoArgs params{};
@@ -247,7 +247,7 @@ NvResult nvhost_ctrl_gpu::ZCullGetInfo(std::span<const u8> input, std::vector<u8
247 return NvResult::Success; 247 return NvResult::Success;
248} 248}
249 249
250NvResult nvhost_ctrl_gpu::ZBCSetTable(std::span<const u8> input, std::vector<u8>& output) { 250NvResult nvhost_ctrl_gpu::ZBCSetTable(std::span<const u8> input, std::span<u8> output) {
251 LOG_WARNING(Service_NVDRV, "(STUBBED) called"); 251 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
252 252
253 IoctlZbcSetTable params{}; 253 IoctlZbcSetTable params{};
@@ -263,7 +263,7 @@ NvResult nvhost_ctrl_gpu::ZBCSetTable(std::span<const u8> input, std::vector<u8>
263 return NvResult::Success; 263 return NvResult::Success;
264} 264}
265 265
266NvResult nvhost_ctrl_gpu::ZBCQueryTable(std::span<const u8> input, std::vector<u8>& output) { 266NvResult nvhost_ctrl_gpu::ZBCQueryTable(std::span<const u8> input, std::span<u8> output) {
267 LOG_WARNING(Service_NVDRV, "(STUBBED) called"); 267 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
268 268
269 IoctlZbcQueryTable params{}; 269 IoctlZbcQueryTable params{};
@@ -273,7 +273,7 @@ NvResult nvhost_ctrl_gpu::ZBCQueryTable(std::span<const u8> input, std::vector<u
273 return NvResult::Success; 273 return NvResult::Success;
274} 274}
275 275
276NvResult nvhost_ctrl_gpu::FlushL2(std::span<const u8> input, std::vector<u8>& output) { 276NvResult nvhost_ctrl_gpu::FlushL2(std::span<const u8> input, std::span<u8> output) {
277 LOG_WARNING(Service_NVDRV, "(STUBBED) called"); 277 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
278 278
279 IoctlFlushL2 params{}; 279 IoctlFlushL2 params{};
@@ -283,7 +283,7 @@ NvResult nvhost_ctrl_gpu::FlushL2(std::span<const u8> input, std::vector<u8>& ou
283 return NvResult::Success; 283 return NvResult::Success;
284} 284}
285 285
286NvResult nvhost_ctrl_gpu::GetGpuTime(std::span<const u8> input, std::vector<u8>& output) { 286NvResult nvhost_ctrl_gpu::GetGpuTime(std::span<const u8> input, std::span<u8> output) {
287 LOG_DEBUG(Service_NVDRV, "called"); 287 LOG_DEBUG(Service_NVDRV, "called");
288 288
289 IoctlGetGpuTime params{}; 289 IoctlGetGpuTime params{};
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
index b9333d9d3..97995551c 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
@@ -22,11 +22,11 @@ public:
22 ~nvhost_ctrl_gpu() override; 22 ~nvhost_ctrl_gpu() override;
23 23
24 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 24 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
25 std::vector<u8>& output) override; 25 std::span<u8> output) override;
26 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 26 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
27 std::span<const u8> inline_input, std::vector<u8>& output) override; 27 std::span<const u8> inline_input, std::span<u8> output) override;
28 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, 28 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
29 std::vector<u8>& inline_output) override; 29 std::span<u8> inline_output) override;
30 30
31 void OnOpen(DeviceFD fd) override; 31 void OnOpen(DeviceFD fd) override;
32 void OnClose(DeviceFD fd) override; 32 void OnClose(DeviceFD fd) override;
@@ -151,21 +151,21 @@ private:
151 }; 151 };
152 static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size"); 152 static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size");
153 153
154 NvResult GetCharacteristics(std::span<const u8> input, std::vector<u8>& output); 154 NvResult GetCharacteristics(std::span<const u8> input, std::span<u8> output);
155 NvResult GetCharacteristics(std::span<const u8> input, std::vector<u8>& output, 155 NvResult GetCharacteristics(std::span<const u8> input, std::span<u8> output,
156 std::vector<u8>& inline_output); 156 std::span<u8> inline_output);
157 157
158 NvResult GetTPCMasks(std::span<const u8> input, std::vector<u8>& output); 158 NvResult GetTPCMasks(std::span<const u8> input, std::span<u8> output);
159 NvResult GetTPCMasks(std::span<const u8> input, std::vector<u8>& output, 159 NvResult GetTPCMasks(std::span<const u8> input, std::span<u8> output,
160 std::vector<u8>& inline_output); 160 std::span<u8> inline_output);
161 161
162 NvResult GetActiveSlotMask(std::span<const u8> input, std::vector<u8>& output); 162 NvResult GetActiveSlotMask(std::span<const u8> input, std::span<u8> output);
163 NvResult ZCullGetCtxSize(std::span<const u8> input, std::vector<u8>& output); 163 NvResult ZCullGetCtxSize(std::span<const u8> input, std::span<u8> output);
164 NvResult ZCullGetInfo(std::span<const u8> input, std::vector<u8>& output); 164 NvResult ZCullGetInfo(std::span<const u8> input, std::span<u8> output);
165 NvResult ZBCSetTable(std::span<const u8> input, std::vector<u8>& output); 165 NvResult ZBCSetTable(std::span<const u8> input, std::span<u8> output);
166 NvResult ZBCQueryTable(std::span<const u8> input, std::vector<u8>& output); 166 NvResult ZBCQueryTable(std::span<const u8> input, std::span<u8> output);
167 NvResult FlushL2(std::span<const u8> input, std::vector<u8>& output); 167 NvResult FlushL2(std::span<const u8> input, std::span<u8> output);
168 NvResult GetGpuTime(std::span<const u8> input, std::vector<u8>& output); 168 NvResult GetGpuTime(std::span<const u8> input, std::span<u8> output);
169 169
170 EventInterface& events_interface; 170 EventInterface& events_interface;
171 171
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 453a965dc..46a25fcab 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -47,7 +47,7 @@ nvhost_gpu::~nvhost_gpu() {
47} 47}
48 48
49NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 49NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
50 std::vector<u8>& output) { 50 std::span<u8> output) {
51 switch (command.group) { 51 switch (command.group) {
52 case 0x0: 52 case 0x0:
53 switch (command.cmd) { 53 switch (command.cmd) {
@@ -99,7 +99,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
99}; 99};
100 100
101NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 101NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
102 std::span<const u8> inline_input, std::vector<u8>& output) { 102 std::span<const u8> inline_input, std::span<u8> output) {
103 switch (command.group) { 103 switch (command.group) {
104 case 'H': 104 case 'H':
105 switch (command.cmd) { 105 switch (command.cmd) {
@@ -113,7 +113,7 @@ NvResult nvhost_gpu::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> inpu
113} 113}
114 114
115NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, 115NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
116 std::vector<u8>& output, std::vector<u8>& inline_output) { 116 std::span<u8> output, std::span<u8> inline_output) {
117 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 117 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
118 return NvResult::NotImplemented; 118 return NvResult::NotImplemented;
119} 119}
@@ -121,7 +121,7 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu
121void nvhost_gpu::OnOpen(DeviceFD fd) {} 121void nvhost_gpu::OnOpen(DeviceFD fd) {}
122void nvhost_gpu::OnClose(DeviceFD fd) {} 122void nvhost_gpu::OnClose(DeviceFD fd) {}
123 123
124NvResult nvhost_gpu::SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output) { 124NvResult nvhost_gpu::SetNVMAPfd(std::span<const u8> input, std::span<u8> output) {
125 IoctlSetNvmapFD params{}; 125 IoctlSetNvmapFD params{};
126 std::memcpy(&params, input.data(), input.size()); 126 std::memcpy(&params, input.data(), input.size());
127 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); 127 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
@@ -130,7 +130,7 @@ NvResult nvhost_gpu::SetNVMAPfd(std::span<const u8> input, std::vector<u8>& outp
130 return NvResult::Success; 130 return NvResult::Success;
131} 131}
132 132
133NvResult nvhost_gpu::SetClientData(std::span<const u8> input, std::vector<u8>& output) { 133NvResult nvhost_gpu::SetClientData(std::span<const u8> input, std::span<u8> output) {
134 LOG_DEBUG(Service_NVDRV, "called"); 134 LOG_DEBUG(Service_NVDRV, "called");
135 135
136 IoctlClientData params{}; 136 IoctlClientData params{};
@@ -139,7 +139,7 @@ NvResult nvhost_gpu::SetClientData(std::span<const u8> input, std::vector<u8>& o
139 return NvResult::Success; 139 return NvResult::Success;
140} 140}
141 141
142NvResult nvhost_gpu::GetClientData(std::span<const u8> input, std::vector<u8>& output) { 142NvResult nvhost_gpu::GetClientData(std::span<const u8> input, std::span<u8> output) {
143 LOG_DEBUG(Service_NVDRV, "called"); 143 LOG_DEBUG(Service_NVDRV, "called");
144 144
145 IoctlClientData params{}; 145 IoctlClientData params{};
@@ -149,7 +149,7 @@ NvResult nvhost_gpu::GetClientData(std::span<const u8> input, std::vector<u8>& o
149 return NvResult::Success; 149 return NvResult::Success;
150} 150}
151 151
152NvResult nvhost_gpu::ZCullBind(std::span<const u8> input, std::vector<u8>& output) { 152NvResult nvhost_gpu::ZCullBind(std::span<const u8> input, std::span<u8> output) {
153 std::memcpy(&zcull_params, input.data(), input.size()); 153 std::memcpy(&zcull_params, input.data(), input.size());
154 LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va, 154 LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va,
155 zcull_params.mode); 155 zcull_params.mode);
@@ -158,7 +158,7 @@ NvResult nvhost_gpu::ZCullBind(std::span<const u8> input, std::vector<u8>& outpu
158 return NvResult::Success; 158 return NvResult::Success;
159} 159}
160 160
161NvResult nvhost_gpu::SetErrorNotifier(std::span<const u8> input, std::vector<u8>& output) { 161NvResult nvhost_gpu::SetErrorNotifier(std::span<const u8> input, std::span<u8> output) {
162 IoctlSetErrorNotifier params{}; 162 IoctlSetErrorNotifier params{};
163 std::memcpy(&params, input.data(), input.size()); 163 std::memcpy(&params, input.data(), input.size());
164 LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset, 164 LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset,
@@ -168,14 +168,14 @@ NvResult nvhost_gpu::SetErrorNotifier(std::span<const u8> input, std::vector<u8>
168 return NvResult::Success; 168 return NvResult::Success;
169} 169}
170 170
171NvResult nvhost_gpu::SetChannelPriority(std::span<const u8> input, std::vector<u8>& output) { 171NvResult nvhost_gpu::SetChannelPriority(std::span<const u8> input, std::span<u8> output) {
172 std::memcpy(&channel_priority, input.data(), input.size()); 172 std::memcpy(&channel_priority, input.data(), input.size());
173 LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority); 173 LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority);
174 174
175 return NvResult::Success; 175 return NvResult::Success;
176} 176}
177 177
178NvResult nvhost_gpu::AllocGPFIFOEx2(std::span<const u8> input, std::vector<u8>& output) { 178NvResult nvhost_gpu::AllocGPFIFOEx2(std::span<const u8> input, std::span<u8> output) {
179 IoctlAllocGpfifoEx2 params{}; 179 IoctlAllocGpfifoEx2 params{};
180 std::memcpy(&params, input.data(), input.size()); 180 std::memcpy(&params, input.data(), input.size());
181 LOG_WARNING(Service_NVDRV, 181 LOG_WARNING(Service_NVDRV,
@@ -197,7 +197,7 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(std::span<const u8> input, std::vector<u8>&
197 return NvResult::Success; 197 return NvResult::Success;
198} 198}
199 199
200NvResult nvhost_gpu::AllocateObjectContext(std::span<const u8> input, std::vector<u8>& output) { 200NvResult nvhost_gpu::AllocateObjectContext(std::span<const u8> input, std::span<u8> output) {
201 IoctlAllocObjCtx params{}; 201 IoctlAllocObjCtx params{};
202 std::memcpy(&params, input.data(), input.size()); 202 std::memcpy(&params, input.data(), input.size());
203 LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num, 203 LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num,
@@ -208,7 +208,8 @@ NvResult nvhost_gpu::AllocateObjectContext(std::span<const u8> input, std::vecto
208 return NvResult::Success; 208 return NvResult::Success;
209} 209}
210 210
211static std::vector<Tegra::CommandHeader> BuildWaitCommandList(NvFence fence) { 211static boost::container::small_vector<Tegra::CommandHeader, 512> BuildWaitCommandList(
212 NvFence fence) {
212 return { 213 return {
213 Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1, 214 Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1,
214 Tegra::SubmissionMode::Increasing), 215 Tegra::SubmissionMode::Increasing),
@@ -219,35 +220,35 @@ static std::vector<Tegra::CommandHeader> BuildWaitCommandList(NvFence fence) {
219 }; 220 };
220} 221}
221 222
222static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(NvFence fence) { 223static boost::container::small_vector<Tegra::CommandHeader, 512> BuildIncrementCommandList(
223 std::vector<Tegra::CommandHeader> result{ 224 NvFence fence) {
225 boost::container::small_vector<Tegra::CommandHeader, 512> result{
224 Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1, 226 Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1,
225 Tegra::SubmissionMode::Increasing), 227 Tegra::SubmissionMode::Increasing),
226 {}}; 228 {}};
227 229
228 for (u32 count = 0; count < 2; ++count) { 230 for (u32 count = 0; count < 2; ++count) {
229 result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointOperation, 1, 231 result.push_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointOperation, 1,
230 Tegra::SubmissionMode::Increasing)); 232 Tegra::SubmissionMode::Increasing));
231 result.emplace_back( 233 result.push_back(
232 BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Increment, fence.id)); 234 BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Increment, fence.id));
233 } 235 }
234 236
235 return result; 237 return result;
236} 238}
237 239
238static std::vector<Tegra::CommandHeader> BuildIncrementWithWfiCommandList(NvFence fence) { 240static boost::container::small_vector<Tegra::CommandHeader, 512> BuildIncrementWithWfiCommandList(
239 std::vector<Tegra::CommandHeader> result{ 241 NvFence fence) {
242 boost::container::small_vector<Tegra::CommandHeader, 512> result{
240 Tegra::BuildCommandHeader(Tegra::BufferMethods::WaitForIdle, 1, 243 Tegra::BuildCommandHeader(Tegra::BufferMethods::WaitForIdle, 1,
241 Tegra::SubmissionMode::Increasing), 244 Tegra::SubmissionMode::Increasing),
242 {}}; 245 {}};
243 const std::vector<Tegra::CommandHeader> increment{BuildIncrementCommandList(fence)}; 246 auto increment_list{BuildIncrementCommandList(fence)};
244 247 result.insert(result.end(), increment_list.begin(), increment_list.end());
245 result.insert(result.end(), increment.begin(), increment.end());
246
247 return result; 248 return result;
248} 249}
249 250
250NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::vector<u8>& output, 251NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> output,
251 Tegra::CommandList&& entries) { 252 Tegra::CommandList&& entries) {
252 LOG_TRACE(Service_NVDRV, "called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address, 253 LOG_TRACE(Service_NVDRV, "called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address,
253 params.num_entries, params.flags.raw); 254 params.num_entries, params.flags.raw);
@@ -293,7 +294,7 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::vector<u8>
293 return NvResult::Success; 294 return NvResult::Success;
294} 295}
295 296
296NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8>& output, 297NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<u8> output,
297 bool kickoff) { 298 bool kickoff) {
298 if (input.size() < sizeof(IoctlSubmitGpfifo)) { 299 if (input.size() < sizeof(IoctlSubmitGpfifo)) {
299 UNIMPLEMENTED(); 300 UNIMPLEMENTED();
@@ -315,7 +316,7 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8>
315} 316}
316 317
317NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline, 318NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline,
318 std::vector<u8>& output) { 319 std::span<u8> output) {
319 if (input.size() < sizeof(IoctlSubmitGpfifo)) { 320 if (input.size() < sizeof(IoctlSubmitGpfifo)) {
320 UNIMPLEMENTED(); 321 UNIMPLEMENTED();
321 return NvResult::InvalidSize; 322 return NvResult::InvalidSize;
@@ -327,7 +328,7 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::span<const
327 return SubmitGPFIFOImpl(params, output, std::move(entries)); 328 return SubmitGPFIFOImpl(params, output, std::move(entries));
328} 329}
329 330
330NvResult nvhost_gpu::GetWaitbase(std::span<const u8> input, std::vector<u8>& output) { 331NvResult nvhost_gpu::GetWaitbase(std::span<const u8> input, std::span<u8> output) {
331 IoctlGetWaitbase params{}; 332 IoctlGetWaitbase params{};
332 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase)); 333 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
333 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); 334 LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
@@ -337,7 +338,7 @@ NvResult nvhost_gpu::GetWaitbase(std::span<const u8> input, std::vector<u8>& out
337 return NvResult::Success; 338 return NvResult::Success;
338} 339}
339 340
340NvResult nvhost_gpu::ChannelSetTimeout(std::span<const u8> input, std::vector<u8>& output) { 341NvResult nvhost_gpu::ChannelSetTimeout(std::span<const u8> input, std::span<u8> output) {
341 IoctlChannelSetTimeout params{}; 342 IoctlChannelSetTimeout params{};
342 std::memcpy(&params, input.data(), sizeof(IoctlChannelSetTimeout)); 343 std::memcpy(&params, input.data(), sizeof(IoctlChannelSetTimeout));
343 LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout); 344 LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout);
@@ -345,7 +346,7 @@ NvResult nvhost_gpu::ChannelSetTimeout(std::span<const u8> input, std::vector<u8
345 return NvResult::Success; 346 return NvResult::Success;
346} 347}
347 348
348NvResult nvhost_gpu::ChannelSetTimeslice(std::span<const u8> input, std::vector<u8>& output) { 349NvResult nvhost_gpu::ChannelSetTimeslice(std::span<const u8> input, std::span<u8> output) {
349 IoctlSetTimeslice params{}; 350 IoctlSetTimeslice params{};
350 std::memcpy(&params, input.data(), sizeof(IoctlSetTimeslice)); 351 std::memcpy(&params, input.data(), sizeof(IoctlSetTimeslice));
351 LOG_INFO(Service_NVDRV, "called, timeslice=0x{:X}", params.timeslice); 352 LOG_INFO(Service_NVDRV, "called, timeslice=0x{:X}", params.timeslice);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index 3ca58202d..529c20526 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -41,11 +41,11 @@ public:
41 ~nvhost_gpu() override; 41 ~nvhost_gpu() override;
42 42
43 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 43 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
44 std::vector<u8>& output) override; 44 std::span<u8> output) override;
45 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 45 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
46 std::span<const u8> inline_input, std::vector<u8>& output) override; 46 std::span<const u8> inline_input, std::span<u8> output) override;
47 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, 47 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
48 std::vector<u8>& inline_output) override; 48 std::span<u8> inline_output) override;
49 49
50 void OnOpen(DeviceFD fd) override; 50 void OnOpen(DeviceFD fd) override;
51 void OnClose(DeviceFD fd) override; 51 void OnClose(DeviceFD fd) override;
@@ -186,23 +186,23 @@ private:
186 u32_le channel_priority{}; 186 u32_le channel_priority{};
187 u32_le channel_timeslice{}; 187 u32_le channel_timeslice{};
188 188
189 NvResult SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output); 189 NvResult SetNVMAPfd(std::span<const u8> input, std::span<u8> output);
190 NvResult SetClientData(std::span<const u8> input, std::vector<u8>& output); 190 NvResult SetClientData(std::span<const u8> input, std::span<u8> output);
191 NvResult GetClientData(std::span<const u8> input, std::vector<u8>& output); 191 NvResult GetClientData(std::span<const u8> input, std::span<u8> output);
192 NvResult ZCullBind(std::span<const u8> input, std::vector<u8>& output); 192 NvResult ZCullBind(std::span<const u8> input, std::span<u8> output);
193 NvResult SetErrorNotifier(std::span<const u8> input, std::vector<u8>& output); 193 NvResult SetErrorNotifier(std::span<const u8> input, std::span<u8> output);
194 NvResult SetChannelPriority(std::span<const u8> input, std::vector<u8>& output); 194 NvResult SetChannelPriority(std::span<const u8> input, std::span<u8> output);
195 NvResult AllocGPFIFOEx2(std::span<const u8> input, std::vector<u8>& output); 195 NvResult AllocGPFIFOEx2(std::span<const u8> input, std::span<u8> output);
196 NvResult AllocateObjectContext(std::span<const u8> input, std::vector<u8>& output); 196 NvResult AllocateObjectContext(std::span<const u8> input, std::span<u8> output);
197 NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::vector<u8>& output, 197 NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::span<u8> output,
198 Tegra::CommandList&& entries); 198 Tegra::CommandList&& entries);
199 NvResult SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8>& output, 199 NvResult SubmitGPFIFOBase(std::span<const u8> input, std::span<u8> output,
200 bool kickoff = false); 200 bool kickoff = false);
201 NvResult SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline, 201 NvResult SubmitGPFIFOBase(std::span<const u8> input, std::span<const u8> input_inline,
202 std::vector<u8>& output); 202 std::span<u8> output);
203 NvResult GetWaitbase(std::span<const u8> input, std::vector<u8>& output); 203 NvResult GetWaitbase(std::span<const u8> input, std::span<u8> output);
204 NvResult ChannelSetTimeout(std::span<const u8> input, std::vector<u8>& output); 204 NvResult ChannelSetTimeout(std::span<const u8> input, std::span<u8> output);
205 NvResult ChannelSetTimeslice(std::span<const u8> input, std::vector<u8>& output); 205 NvResult ChannelSetTimeslice(std::span<const u8> input, std::span<u8> output);
206 206
207 EventInterface& events_interface; 207 EventInterface& events_interface;
208 NvCore::Container& core; 208 NvCore::Container& core;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index dc45169ad..a174442a6 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -16,7 +16,7 @@ nvhost_nvdec::nvhost_nvdec(Core::System& system_, NvCore::Container& core_)
16nvhost_nvdec::~nvhost_nvdec() = default; 16nvhost_nvdec::~nvhost_nvdec() = default;
17 17
18NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 18NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
19 std::vector<u8>& output) { 19 std::span<u8> output) {
20 switch (command.group) { 20 switch (command.group) {
21 case 0x0: 21 case 0x0:
22 switch (command.cmd) { 22 switch (command.cmd) {
@@ -56,13 +56,13 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in
56} 56}
57 57
58NvResult nvhost_nvdec::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 58NvResult nvhost_nvdec::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
59 std::span<const u8> inline_input, std::vector<u8>& output) { 59 std::span<const u8> inline_input, std::span<u8> output) {
60 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 60 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
61 return NvResult::NotImplemented; 61 return NvResult::NotImplemented;
62} 62}
63 63
64NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, 64NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
65 std::vector<u8>& output, std::vector<u8>& inline_output) { 65 std::span<u8> output, std::span<u8> inline_output) {
66 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 66 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
67 return NvResult::NotImplemented; 67 return NvResult::NotImplemented;
68} 68}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index 0d615bbcb..ad2233c49 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -14,11 +14,11 @@ public:
14 ~nvhost_nvdec() override; 14 ~nvhost_nvdec() override;
15 15
16 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 16 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
17 std::vector<u8>& output) override; 17 std::span<u8> output) override;
18 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 18 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
19 std::span<const u8> inline_input, std::vector<u8>& output) override; 19 std::span<const u8> inline_input, std::span<u8> output) override;
20 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, 20 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
21 std::vector<u8>& inline_output) override; 21 std::span<u8> inline_output) override;
22 22
23 void OnOpen(DeviceFD fd) override; 23 void OnOpen(DeviceFD fd) override;
24 void OnClose(DeviceFD fd) override; 24 void OnClose(DeviceFD fd) override;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
index 1ab51f10b..61649aa4a 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -36,7 +36,7 @@ std::size_t SliceVectors(std::span<const u8> input, std::vector<T>& dst, std::si
36// Writes the data in src to an offset into the dst vector. The offset is specified in bytes 36// Writes the data in src to an offset into the dst vector. The offset is specified in bytes
37// Returns the number of bytes written into dst. 37// Returns the number of bytes written into dst.
38template <typename T> 38template <typename T>
39std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::size_t offset) { 39std::size_t WriteVectors(std::span<u8> dst, const std::vector<T>& src, std::size_t offset) {
40 if (src.empty()) { 40 if (src.empty()) {
41 return 0; 41 return 0;
42 } 42 }
@@ -72,8 +72,7 @@ NvResult nvhost_nvdec_common::SetNVMAPfd(std::span<const u8> input) {
72 return NvResult::Success; 72 return NvResult::Success;
73} 73}
74 74
75NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, 75NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input, std::span<u8> output) {
76 std::vector<u8>& output) {
77 IoctlSubmit params{}; 76 IoctlSubmit params{};
78 std::memcpy(&params, input.data(), sizeof(IoctlSubmit)); 77 std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
79 LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); 78 LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count);
@@ -121,7 +120,7 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input,
121 return NvResult::Success; 120 return NvResult::Success;
122} 121}
123 122
124NvResult nvhost_nvdec_common::GetSyncpoint(std::span<const u8> input, std::vector<u8>& output) { 123NvResult nvhost_nvdec_common::GetSyncpoint(std::span<const u8> input, std::span<u8> output) {
125 IoctlGetSyncpoint params{}; 124 IoctlGetSyncpoint params{};
126 std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint)); 125 std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
127 LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); 126 LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param);
@@ -133,7 +132,7 @@ NvResult nvhost_nvdec_common::GetSyncpoint(std::span<const u8> input, std::vecto
133 return NvResult::Success; 132 return NvResult::Success;
134} 133}
135 134
136NvResult nvhost_nvdec_common::GetWaitbase(std::span<const u8> input, std::vector<u8>& output) { 135NvResult nvhost_nvdec_common::GetWaitbase(std::span<const u8> input, std::span<u8> output) {
137 IoctlGetWaitbase params{}; 136 IoctlGetWaitbase params{};
138 LOG_CRITICAL(Service_NVDRV, "called WAITBASE"); 137 LOG_CRITICAL(Service_NVDRV, "called WAITBASE");
139 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase)); 138 std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
@@ -142,7 +141,7 @@ NvResult nvhost_nvdec_common::GetWaitbase(std::span<const u8> input, std::vector
142 return NvResult::Success; 141 return NvResult::Success;
143} 142}
144 143
145NvResult nvhost_nvdec_common::MapBuffer(std::span<const u8> input, std::vector<u8>& output) { 144NvResult nvhost_nvdec_common::MapBuffer(std::span<const u8> input, std::span<u8> output) {
146 IoctlMapBuffer params{}; 145 IoctlMapBuffer params{};
147 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer)); 146 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
148 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); 147 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries);
@@ -159,7 +158,7 @@ NvResult nvhost_nvdec_common::MapBuffer(std::span<const u8> input, std::vector<u
159 return NvResult::Success; 158 return NvResult::Success;
160} 159}
161 160
162NvResult nvhost_nvdec_common::UnmapBuffer(std::span<const u8> input, std::vector<u8>& output) { 161NvResult nvhost_nvdec_common::UnmapBuffer(std::span<const u8> input, std::span<u8> output) {
163 IoctlMapBuffer params{}; 162 IoctlMapBuffer params{};
164 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer)); 163 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
165 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); 164 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries);
@@ -173,7 +172,7 @@ NvResult nvhost_nvdec_common::UnmapBuffer(std::span<const u8> input, std::vector
173 return NvResult::Success; 172 return NvResult::Success;
174} 173}
175 174
176NvResult nvhost_nvdec_common::SetSubmitTimeout(std::span<const u8> input, std::vector<u8>& output) { 175NvResult nvhost_nvdec_common::SetSubmitTimeout(std::span<const u8> input, std::span<u8> output) {
177 std::memcpy(&submit_timeout, input.data(), input.size()); 176 std::memcpy(&submit_timeout, input.data(), input.size());
178 LOG_WARNING(Service_NVDRV, "(STUBBED) called"); 177 LOG_WARNING(Service_NVDRV, "(STUBBED) called");
179 return NvResult::Success; 178 return NvResult::Success;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
index 5af26a26f..9bb573bfe 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
@@ -108,12 +108,12 @@ protected:
108 108
109 /// Ioctl command implementations 109 /// Ioctl command implementations
110 NvResult SetNVMAPfd(std::span<const u8> input); 110 NvResult SetNVMAPfd(std::span<const u8> input);
111 NvResult Submit(DeviceFD fd, std::span<const u8> input, std::vector<u8>& output); 111 NvResult Submit(DeviceFD fd, std::span<const u8> input, std::span<u8> output);
112 NvResult GetSyncpoint(std::span<const u8> input, std::vector<u8>& output); 112 NvResult GetSyncpoint(std::span<const u8> input, std::span<u8> output);
113 NvResult GetWaitbase(std::span<const u8> input, std::vector<u8>& output); 113 NvResult GetWaitbase(std::span<const u8> input, std::span<u8> output);
114 NvResult MapBuffer(std::span<const u8> input, std::vector<u8>& output); 114 NvResult MapBuffer(std::span<const u8> input, std::span<u8> output);
115 NvResult UnmapBuffer(std::span<const u8> input, std::vector<u8>& output); 115 NvResult UnmapBuffer(std::span<const u8> input, std::span<u8> output);
116 NvResult SetSubmitTimeout(std::span<const u8> input, std::vector<u8>& output); 116 NvResult SetSubmitTimeout(std::span<const u8> input, std::span<u8> output);
117 117
118 Kernel::KEvent* QueryEvent(u32 event_id) override; 118 Kernel::KEvent* QueryEvent(u32 event_id) override;
119 119
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
index 39f30e7c8..a05c8cdae 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
@@ -13,7 +13,7 @@ nvhost_nvjpg::nvhost_nvjpg(Core::System& system_) : nvdevice{system_} {}
13nvhost_nvjpg::~nvhost_nvjpg() = default; 13nvhost_nvjpg::~nvhost_nvjpg() = default;
14 14
15NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 15NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
16 std::vector<u8>& output) { 16 std::span<u8> output) {
17 switch (command.group) { 17 switch (command.group) {
18 case 'H': 18 case 'H':
19 switch (command.cmd) { 19 switch (command.cmd) {
@@ -32,13 +32,13 @@ NvResult nvhost_nvjpg::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in
32} 32}
33 33
34NvResult nvhost_nvjpg::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 34NvResult nvhost_nvjpg::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
35 std::span<const u8> inline_input, std::vector<u8>& output) { 35 std::span<const u8> inline_input, std::span<u8> output) {
36 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 36 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
37 return NvResult::NotImplemented; 37 return NvResult::NotImplemented;
38} 38}
39 39
40NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, 40NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
41 std::vector<u8>& output, std::vector<u8>& inline_output) { 41 std::span<u8> output, std::span<u8> inline_output) {
42 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 42 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
43 return NvResult::NotImplemented; 43 return NvResult::NotImplemented;
44} 44}
@@ -46,7 +46,7 @@ NvResult nvhost_nvjpg::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> in
46void nvhost_nvjpg::OnOpen(DeviceFD fd) {} 46void nvhost_nvjpg::OnOpen(DeviceFD fd) {}
47void nvhost_nvjpg::OnClose(DeviceFD fd) {} 47void nvhost_nvjpg::OnClose(DeviceFD fd) {}
48 48
49NvResult nvhost_nvjpg::SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output) { 49NvResult nvhost_nvjpg::SetNVMAPfd(std::span<const u8> input, std::span<u8> output) {
50 IoctlSetNvmapFD params{}; 50 IoctlSetNvmapFD params{};
51 std::memcpy(&params, input.data(), input.size()); 51 std::memcpy(&params, input.data(), input.size());
52 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); 52 LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
index 41b57e872..5623e0d47 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
@@ -16,11 +16,11 @@ public:
16 ~nvhost_nvjpg() override; 16 ~nvhost_nvjpg() override;
17 17
18 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 18 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
19 std::vector<u8>& output) override; 19 std::span<u8> output) override;
20 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 20 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
21 std::span<const u8> inline_input, std::vector<u8>& output) override; 21 std::span<const u8> inline_input, std::span<u8> output) override;
22 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, 22 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
23 std::vector<u8>& inline_output) override; 23 std::span<u8> inline_output) override;
24 24
25 void OnOpen(DeviceFD fd) override; 25 void OnOpen(DeviceFD fd) override;
26 void OnClose(DeviceFD fd) override; 26 void OnClose(DeviceFD fd) override;
@@ -33,7 +33,7 @@ private:
33 33
34 s32_le nvmap_fd{}; 34 s32_le nvmap_fd{};
35 35
36 NvResult SetNVMAPfd(std::span<const u8> input, std::vector<u8>& output); 36 NvResult SetNVMAPfd(std::span<const u8> input, std::span<u8> output);
37}; 37};
38 38
39} // namespace Service::Nvidia::Devices 39} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index b0ea402a7..c0b8684c3 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -16,7 +16,7 @@ nvhost_vic::nvhost_vic(Core::System& system_, NvCore::Container& core_)
16nvhost_vic::~nvhost_vic() = default; 16nvhost_vic::~nvhost_vic() = default;
17 17
18NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 18NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
19 std::vector<u8>& output) { 19 std::span<u8> output) {
20 switch (command.group) { 20 switch (command.group) {
21 case 0x0: 21 case 0x0:
22 switch (command.cmd) { 22 switch (command.cmd) {
@@ -56,13 +56,13 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
56} 56}
57 57
58NvResult nvhost_vic::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 58NvResult nvhost_vic::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
59 std::span<const u8> inline_input, std::vector<u8>& output) { 59 std::span<const u8> inline_input, std::span<u8> output) {
60 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 60 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
61 return NvResult::NotImplemented; 61 return NvResult::NotImplemented;
62} 62}
63 63
64NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, 64NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
65 std::vector<u8>& output, std::vector<u8>& inline_output) { 65 std::span<u8> output, std::span<u8> inline_output) {
66 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 66 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
67 return NvResult::NotImplemented; 67 return NvResult::NotImplemented;
68} 68}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index b5e350a83..cadbcb0a5 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -13,11 +13,11 @@ public:
13 ~nvhost_vic(); 13 ~nvhost_vic();
14 14
15 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 15 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
16 std::vector<u8>& output) override; 16 std::span<u8> output) override;
17 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 17 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
18 std::span<const u8> inline_input, std::vector<u8>& output) override; 18 std::span<const u8> inline_input, std::span<u8> output) override;
19 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, 19 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
20 std::vector<u8>& inline_output) override; 20 std::span<u8> inline_output) override;
21 21
22 void OnOpen(DeviceFD fd) override; 22 void OnOpen(DeviceFD fd) override;
23 void OnClose(DeviceFD fd) override; 23 void OnClose(DeviceFD fd) override;
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 07417f045..e7f7e273b 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -26,7 +26,7 @@ nvmap::nvmap(Core::System& system_, NvCore::Container& container_)
26nvmap::~nvmap() = default; 26nvmap::~nvmap() = default;
27 27
28NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 28NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
29 std::vector<u8>& output) { 29 std::span<u8> output) {
30 switch (command.group) { 30 switch (command.group) {
31 case 0x1: 31 case 0x1:
32 switch (command.cmd) { 32 switch (command.cmd) {
@@ -55,13 +55,13 @@ NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
55} 55}
56 56
57NvResult nvmap::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 57NvResult nvmap::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
58 std::span<const u8> inline_input, std::vector<u8>& output) { 58 std::span<const u8> inline_input, std::span<u8> output) {
59 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 59 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
60 return NvResult::NotImplemented; 60 return NvResult::NotImplemented;
61} 61}
62 62
63NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, 63NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
64 std::vector<u8>& output, std::vector<u8>& inline_output) { 64 std::span<u8> inline_output) {
65 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); 65 UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
66 return NvResult::NotImplemented; 66 return NvResult::NotImplemented;
67} 67}
@@ -69,7 +69,7 @@ NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input,
69void nvmap::OnOpen(DeviceFD fd) {} 69void nvmap::OnOpen(DeviceFD fd) {}
70void nvmap::OnClose(DeviceFD fd) {} 70void nvmap::OnClose(DeviceFD fd) {}
71 71
72NvResult nvmap::IocCreate(std::span<const u8> input, std::vector<u8>& output) { 72NvResult nvmap::IocCreate(std::span<const u8> input, std::span<u8> output) {
73 IocCreateParams params; 73 IocCreateParams params;
74 std::memcpy(&params, input.data(), sizeof(params)); 74 std::memcpy(&params, input.data(), sizeof(params));
75 LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size); 75 LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size);
@@ -89,7 +89,7 @@ NvResult nvmap::IocCreate(std::span<const u8> input, std::vector<u8>& output) {
89 return NvResult::Success; 89 return NvResult::Success;
90} 90}
91 91
92NvResult nvmap::IocAlloc(std::span<const u8> input, std::vector<u8>& output) { 92NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) {
93 IocAllocParams params; 93 IocAllocParams params;
94 std::memcpy(&params, input.data(), sizeof(params)); 94 std::memcpy(&params, input.data(), sizeof(params));
95 LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address); 95 LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address);
@@ -137,7 +137,7 @@ NvResult nvmap::IocAlloc(std::span<const u8> input, std::vector<u8>& output) {
137 return result; 137 return result;
138} 138}
139 139
140NvResult nvmap::IocGetId(std::span<const u8> input, std::vector<u8>& output) { 140NvResult nvmap::IocGetId(std::span<const u8> input, std::span<u8> output) {
141 IocGetIdParams params; 141 IocGetIdParams params;
142 std::memcpy(&params, input.data(), sizeof(params)); 142 std::memcpy(&params, input.data(), sizeof(params));
143 143
@@ -161,7 +161,7 @@ NvResult nvmap::IocGetId(std::span<const u8> input, std::vector<u8>& output) {
161 return NvResult::Success; 161 return NvResult::Success;
162} 162}
163 163
164NvResult nvmap::IocFromId(std::span<const u8> input, std::vector<u8>& output) { 164NvResult nvmap::IocFromId(std::span<const u8> input, std::span<u8> output) {
165 IocFromIdParams params; 165 IocFromIdParams params;
166 std::memcpy(&params, input.data(), sizeof(params)); 166 std::memcpy(&params, input.data(), sizeof(params));
167 167
@@ -192,7 +192,7 @@ NvResult nvmap::IocFromId(std::span<const u8> input, std::vector<u8>& output) {
192 return NvResult::Success; 192 return NvResult::Success;
193} 193}
194 194
195NvResult nvmap::IocParam(std::span<const u8> input, std::vector<u8>& output) { 195NvResult nvmap::IocParam(std::span<const u8> input, std::span<u8> output) {
196 enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; 196 enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 };
197 197
198 IocParamParams params; 198 IocParamParams params;
@@ -241,7 +241,7 @@ NvResult nvmap::IocParam(std::span<const u8> input, std::vector<u8>& output) {
241 return NvResult::Success; 241 return NvResult::Success;
242} 242}
243 243
244NvResult nvmap::IocFree(std::span<const u8> input, std::vector<u8>& output) { 244NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) {
245 IocFreeParams params; 245 IocFreeParams params;
246 std::memcpy(&params, input.data(), sizeof(params)); 246 std::memcpy(&params, input.data(), sizeof(params));
247 247
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h
index 82bd3b118..40c65b430 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.h
+++ b/src/core/hle/service/nvdrv/devices/nvmap.h
@@ -27,11 +27,11 @@ public:
27 nvmap& operator=(const nvmap&) = delete; 27 nvmap& operator=(const nvmap&) = delete;
28 28
29 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 29 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
30 std::vector<u8>& output) override; 30 std::span<u8> output) override;
31 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 31 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
32 std::span<const u8> inline_input, std::vector<u8>& output) override; 32 std::span<const u8> inline_input, std::span<u8> output) override;
33 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, 33 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
34 std::vector<u8>& inline_output) override; 34 std::span<u8> inline_output) override;
35 35
36 void OnOpen(DeviceFD fd) override; 36 void OnOpen(DeviceFD fd) override;
37 void OnClose(DeviceFD fd) override; 37 void OnClose(DeviceFD fd) override;
@@ -106,12 +106,12 @@ private:
106 }; 106 };
107 static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size"); 107 static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size");
108 108
109 NvResult IocCreate(std::span<const u8> input, std::vector<u8>& output); 109 NvResult IocCreate(std::span<const u8> input, std::span<u8> output);
110 NvResult IocAlloc(std::span<const u8> input, std::vector<u8>& output); 110 NvResult IocAlloc(std::span<const u8> input, std::span<u8> output);
111 NvResult IocGetId(std::span<const u8> input, std::vector<u8>& output); 111 NvResult IocGetId(std::span<const u8> input, std::span<u8> output);
112 NvResult IocFromId(std::span<const u8> input, std::vector<u8>& output); 112 NvResult IocFromId(std::span<const u8> input, std::span<u8> output);
113 NvResult IocParam(std::span<const u8> input, std::vector<u8>& output); 113 NvResult IocParam(std::span<const u8> input, std::span<u8> output);
114 NvResult IocFree(std::span<const u8> input, std::vector<u8>& output); 114 NvResult IocFree(std::span<const u8> input, std::span<u8> output);
115 115
116 NvCore::Container& container; 116 NvCore::Container& container;
117 NvCore::NvMap& file; 117 NvCore::NvMap& file;
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 3d774eec4..9e46ee8dd 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -130,7 +130,7 @@ DeviceFD Module::Open(const std::string& device_name) {
130} 130}
131 131
132NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, 132NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
133 std::vector<u8>& output) { 133 std::span<u8> output) {
134 if (fd < 0) { 134 if (fd < 0) {
135 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); 135 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
136 return NvResult::InvalidState; 136 return NvResult::InvalidState;
@@ -147,7 +147,7 @@ NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
147} 147}
148 148
149NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 149NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
150 std::span<const u8> inline_input, std::vector<u8>& output) { 150 std::span<const u8> inline_input, std::span<u8> output) {
151 if (fd < 0) { 151 if (fd < 0) {
152 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); 152 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
153 return NvResult::InvalidState; 153 return NvResult::InvalidState;
@@ -163,8 +163,8 @@ NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
163 return itr->second->Ioctl2(fd, command, input, inline_input, output); 163 return itr->second->Ioctl2(fd, command, input, inline_input, output);
164} 164}
165 165
166NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, 166NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
167 std::vector<u8>& output, std::vector<u8>& inline_output) { 167 std::span<u8> inline_output) {
168 if (fd < 0) { 168 if (fd < 0) {
169 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); 169 LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
170 return NvResult::InvalidState; 170 return NvResult::InvalidState;
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index 668be742b..d8622b3ca 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -80,13 +80,13 @@ public:
80 DeviceFD Open(const std::string& device_name); 80 DeviceFD Open(const std::string& device_name);
81 81
82 /// Sends an ioctl command to the specified file descriptor. 82 /// Sends an ioctl command to the specified file descriptor.
83 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output); 83 NvResult Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output);
84 84
85 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input, 85 NvResult Ioctl2(DeviceFD fd, Ioctl command, std::span<const u8> input,
86 std::span<const u8> inline_input, std::vector<u8>& output); 86 std::span<const u8> inline_input, std::span<u8> output);
87 87
88 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::vector<u8>& output, 88 NvResult Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, std::span<u8> output,
89 std::vector<u8>& inline_output); 89 std::span<u8> inline_output);
90 90
91 /// Closes a device file descriptor and returns operation success. 91 /// Closes a device file descriptor and returns operation success.
92 NvResult Close(DeviceFD fd); 92 NvResult Close(DeviceFD fd);
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
index d010a1e03..348207e25 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
@@ -63,12 +63,12 @@ void NVDRV::Ioctl1(HLERequestContext& ctx) {
63 } 63 }
64 64
65 // Check device 65 // Check device
66 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); 66 tmp_output.resize_destructive(ctx.GetWriteBufferSize(0));
67 const auto input_buffer = ctx.ReadBuffer(0); 67 const auto input_buffer = ctx.ReadBuffer(0);
68 68
69 const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, output_buffer); 69 const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, tmp_output);
70 if (command.is_out != 0) { 70 if (command.is_out != 0) {
71 ctx.WriteBuffer(output_buffer); 71 ctx.WriteBuffer(tmp_output);
72 } 72 }
73 73
74 IPC::ResponseBuilder rb{ctx, 3}; 74 IPC::ResponseBuilder rb{ctx, 3};
@@ -90,12 +90,12 @@ void NVDRV::Ioctl2(HLERequestContext& ctx) {
90 90
91 const auto input_buffer = ctx.ReadBuffer(0); 91 const auto input_buffer = ctx.ReadBuffer(0);
92 const auto input_inlined_buffer = ctx.ReadBuffer(1); 92 const auto input_inlined_buffer = ctx.ReadBuffer(1);
93 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); 93 tmp_output.resize_destructive(ctx.GetWriteBufferSize(0));
94 94
95 const auto nv_result = 95 const auto nv_result =
96 nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, output_buffer); 96 nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, tmp_output);
97 if (command.is_out != 0) { 97 if (command.is_out != 0) {
98 ctx.WriteBuffer(output_buffer); 98 ctx.WriteBuffer(tmp_output);
99 } 99 }
100 100
101 IPC::ResponseBuilder rb{ctx, 3}; 101 IPC::ResponseBuilder rb{ctx, 3};
@@ -116,14 +116,12 @@ void NVDRV::Ioctl3(HLERequestContext& ctx) {
116 } 116 }
117 117
118 const auto input_buffer = ctx.ReadBuffer(0); 118 const auto input_buffer = ctx.ReadBuffer(0);
119 std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); 119 tmp_output.resize_destructive(ctx.GetWriteBufferSize(0));
120 std::vector<u8> output_buffer_inline(ctx.GetWriteBufferSize(1)); 120 tmp_output_inline.resize_destructive(ctx.GetWriteBufferSize(1));
121 121 const auto nv_result = nvdrv->Ioctl3(fd, command, input_buffer, tmp_output, tmp_output_inline);
122 const auto nv_result =
123 nvdrv->Ioctl3(fd, command, input_buffer, output_buffer, output_buffer_inline);
124 if (command.is_out != 0) { 122 if (command.is_out != 0) {
125 ctx.WriteBuffer(output_buffer, 0); 123 ctx.WriteBuffer(tmp_output, 0);
126 ctx.WriteBuffer(output_buffer_inline, 1); 124 ctx.WriteBuffer(tmp_output_inline, 1);
127 } 125 }
128 126
129 IPC::ResponseBuilder rb{ctx, 3}; 127 IPC::ResponseBuilder rb{ctx, 3};
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h
index 881ea1a6b..4b593ff90 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.h
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.h
@@ -4,6 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include <memory> 6#include <memory>
7#include "common/scratch_buffer.h"
7#include "core/hle/service/nvdrv/nvdrv.h" 8#include "core/hle/service/nvdrv/nvdrv.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9 10
@@ -33,6 +34,8 @@ private:
33 34
34 u64 pid{}; 35 u64 pid{};
35 bool is_initialized{}; 36 bool is_initialized{};
37 Common::ScratchBuffer<u8> tmp_output;
38 Common::ScratchBuffer<u8> tmp_output_inline;
36}; 39};
37 40
38} // namespace Service::Nvidia 41} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvnflinger/parcel.h b/src/core/hle/service/nvnflinger/parcel.h
index fb56d75d7..23ba315a0 100644
--- a/src/core/hle/service/nvnflinger/parcel.h
+++ b/src/core/hle/service/nvnflinger/parcel.h
@@ -6,6 +6,7 @@
6#include <memory> 6#include <memory>
7#include <span> 7#include <span>
8#include <vector> 8#include <vector>
9#include <boost/container/small_vector.hpp>
9 10
10#include "common/alignment.h" 11#include "common/alignment.h"
11#include "common/assert.h" 12#include "common/assert.h"
@@ -167,7 +168,7 @@ public:
167private: 168private:
168 template <typename T> 169 template <typename T>
169 requires(std::is_trivially_copyable_v<T>) 170 requires(std::is_trivially_copyable_v<T>)
170 void WriteImpl(const T& val, std::vector<u8>& buffer) { 171 void WriteImpl(const T& val, boost::container::small_vector<u8, 0x200>& buffer) {
171 const size_t aligned_size = Common::AlignUp(sizeof(T), 4); 172 const size_t aligned_size = Common::AlignUp(sizeof(T), 4);
172 const size_t old_size = buffer.size(); 173 const size_t old_size = buffer.size();
173 buffer.resize(old_size + aligned_size); 174 buffer.resize(old_size + aligned_size);
@@ -176,8 +177,8 @@ private:
176 } 177 }
177 178
178private: 179private:
179 std::vector<u8> m_data_buffer; 180 boost::container::small_vector<u8, 0x200> m_data_buffer;
180 std::vector<u8> m_object_buffer; 181 boost::container::small_vector<u8, 0x200> m_object_buffer;
181}; 182};
182 183
183} // namespace Service::android 184} // namespace Service::android