summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/audio_renderer.cpp10
-rw-r--r--src/audio_core/audio_renderer.h25
-rw-r--r--src/core/hle/service/acc/acc.cpp14
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdevice.h6
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp18
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp20
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.h5
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp75
-rw-r--r--src/core/hle/service/nvdrv/interface.h3
-rw-r--r--src/core/hle/service/nvdrv/nvdata.h6
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp7
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h5
27 files changed, 184 insertions, 91 deletions
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index da50a0bbc..e6f38d600 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -107,6 +107,11 @@ Stream::State AudioRenderer::GetStreamState() const {
107 return stream->GetState(); 107 return stream->GetState();
108} 108}
109 109
110static constexpr u32 VersionFromRevision(u32_le rev) {
111 // "REV7" -> 7
112 return ((rev >> 24) & 0xff) - 0x30;
113}
114
110std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params) { 115std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params) {
111 // Copy UpdateDataHeader struct 116 // Copy UpdateDataHeader struct
112 UpdateDataHeader config{}; 117 UpdateDataHeader config{};
@@ -166,6 +171,11 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
166 // Copy output header 171 // Copy output header
167 UpdateDataHeader response_data{worker_params}; 172 UpdateDataHeader response_data{worker_params};
168 std::vector<u8> output_params(response_data.total_size); 173 std::vector<u8> output_params(response_data.total_size);
174 const auto audren_revision = VersionFromRevision(config.revision);
175 if (audren_revision >= 5) {
176 response_data.frame_count = 0x10;
177 response_data.total_size += 0x10;
178 }
169 std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader)); 179 std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader));
170 180
171 // Copy output memory pool entries 181 // Copy output memory pool entries
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
index 45afbe759..4f14b91cd 100644
--- a/src/audio_core/audio_renderer.h
+++ b/src/audio_core/audio_renderer.h
@@ -194,21 +194,24 @@ struct UpdateDataHeader {
194 mixes_size = 0x0; 194 mixes_size = 0x0;
195 sinks_size = config.sink_count * 0x20; 195 sinks_size = config.sink_count * 0x20;
196 performance_manager_size = 0x10; 196 performance_manager_size = 0x10;
197 frame_count = 0;
197 total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size + 198 total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size +
198 effects_size + sinks_size + performance_manager_size; 199 effects_size + sinks_size + performance_manager_size;
199 } 200 }
200 201
201 u32_le revision; 202 u32_le revision{};
202 u32_le behavior_size; 203 u32_le behavior_size{};
203 u32_le memory_pools_size; 204 u32_le memory_pools_size{};
204 u32_le voices_size; 205 u32_le voices_size{};
205 u32_le voice_resource_size; 206 u32_le voice_resource_size{};
206 u32_le effects_size; 207 u32_le effects_size{};
207 u32_le mixes_size; 208 u32_le mixes_size{};
208 u32_le sinks_size; 209 u32_le sinks_size{};
209 u32_le performance_manager_size; 210 u32_le performance_manager_size{};
210 INSERT_PADDING_WORDS(6); 211 INSERT_PADDING_WORDS(1);
211 u32_le total_size; 212 u32_le frame_count{};
213 INSERT_PADDING_WORDS(4);
214 u32_le total_size{};
212}; 215};
213static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); 216static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size");
214 217
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index a7c55e116..0c0f7ed6e 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -70,7 +70,7 @@ public:
70 70
71protected: 71protected:
72 void Get(Kernel::HLERequestContext& ctx) { 72 void Get(Kernel::HLERequestContext& ctx) {
73 LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); 73 LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format());
74 ProfileBase profile_base{}; 74 ProfileBase profile_base{};
75 ProfileData data{}; 75 ProfileData data{};
76 if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) { 76 if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) {
@@ -89,7 +89,7 @@ protected:
89 } 89 }
90 90
91 void GetBase(Kernel::HLERequestContext& ctx) { 91 void GetBase(Kernel::HLERequestContext& ctx) {
92 LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); 92 LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format());
93 ProfileBase profile_base{}; 93 ProfileBase profile_base{};
94 if (profile_manager.GetProfileBase(user_id, profile_base)) { 94 if (profile_manager.GetProfileBase(user_id, profile_base)) {
95 IPC::ResponseBuilder rb{ctx, 16}; 95 IPC::ResponseBuilder rb{ctx, 16};
@@ -263,7 +263,7 @@ private:
263}; 263};
264 264
265void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) { 265void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) {
266 LOG_INFO(Service_ACC, "called"); 266 LOG_DEBUG(Service_ACC, "called");
267 IPC::ResponseBuilder rb{ctx, 3}; 267 IPC::ResponseBuilder rb{ctx, 3};
268 rb.Push(RESULT_SUCCESS); 268 rb.Push(RESULT_SUCCESS);
269 rb.Push<u32>(static_cast<u32>(profile_manager->GetUserCount())); 269 rb.Push<u32>(static_cast<u32>(profile_manager->GetUserCount()));
@@ -272,7 +272,7 @@ void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) {
272void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { 272void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) {
273 IPC::RequestParser rp{ctx}; 273 IPC::RequestParser rp{ctx};
274 Common::UUID user_id = rp.PopRaw<Common::UUID>(); 274 Common::UUID user_id = rp.PopRaw<Common::UUID>();
275 LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); 275 LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format());
276 276
277 IPC::ResponseBuilder rb{ctx, 3}; 277 IPC::ResponseBuilder rb{ctx, 3};
278 rb.Push(RESULT_SUCCESS); 278 rb.Push(RESULT_SUCCESS);
@@ -280,21 +280,21 @@ void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) {
280} 280}
281 281
282void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { 282void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) {
283 LOG_INFO(Service_ACC, "called"); 283 LOG_DEBUG(Service_ACC, "called");
284 ctx.WriteBuffer(profile_manager->GetAllUsers()); 284 ctx.WriteBuffer(profile_manager->GetAllUsers());
285 IPC::ResponseBuilder rb{ctx, 2}; 285 IPC::ResponseBuilder rb{ctx, 2};
286 rb.Push(RESULT_SUCCESS); 286 rb.Push(RESULT_SUCCESS);
287} 287}
288 288
289void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { 289void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) {
290 LOG_INFO(Service_ACC, "called"); 290 LOG_DEBUG(Service_ACC, "called");
291 ctx.WriteBuffer(profile_manager->GetOpenUsers()); 291 ctx.WriteBuffer(profile_manager->GetOpenUsers());
292 IPC::ResponseBuilder rb{ctx, 2}; 292 IPC::ResponseBuilder rb{ctx, 2};
293 rb.Push(RESULT_SUCCESS); 293 rb.Push(RESULT_SUCCESS);
294} 294}
295 295
296void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { 296void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) {
297 LOG_INFO(Service_ACC, "called"); 297 LOG_DEBUG(Service_ACC, "called");
298 IPC::ResponseBuilder rb{ctx, 6}; 298 IPC::ResponseBuilder rb{ctx, 6};
299 rb.Push(RESULT_SUCCESS); 299 rb.Push(RESULT_SUCCESS);
300 rb.PushRaw<Common::UUID>(profile_manager->GetLastOpenedUser()); 300 rb.PushRaw<Common::UUID>(profile_manager->GetLastOpenedUser());
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h
index 5b8248433..1b52511a5 100644
--- a/src/core/hle/service/nvdrv/devices/nvdevice.h
+++ b/src/core/hle/service/nvdrv/devices/nvdevice.h
@@ -9,6 +9,7 @@
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "common/swap.h" 10#include "common/swap.h"
11#include "core/hle/service/nvdrv/nvdata.h" 11#include "core/hle/service/nvdrv/nvdata.h"
12#include "core/hle/service/service.h"
12 13
13namespace Core { 14namespace Core {
14class System; 15class System;
@@ -38,8 +39,9 @@ public:
38 * @param output A buffer where the output data will be written to. 39 * @param output A buffer where the output data will be written to.
39 * @returns The result code of the ioctl. 40 * @returns The result code of the ioctl.
40 */ 41 */
41 virtual u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 42 virtual u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
42 IoctlCtrl& ctrl) = 0; 43 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
44 IoctlVersion version) = 0;
43 45
44protected: 46protected:
45 Core::System& system; 47 Core::System& system;
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index 926a1285d..f764388bc 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -17,8 +17,9 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_de
17 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} 17 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
18nvdisp_disp0 ::~nvdisp_disp0() = default; 18nvdisp_disp0 ::~nvdisp_disp0() = default;
19 19
20u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 20u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
21 IoctlCtrl& ctrl) { 21 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
22 IoctlVersion version) {
22 UNIMPLEMENTED_MSG("Unimplemented ioctl"); 23 UNIMPLEMENTED_MSG("Unimplemented ioctl");
23 return 0; 24 return 0;
24} 25}
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
index e79e490ff..6fcdeee84 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
@@ -20,8 +20,9 @@ public:
20 explicit nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); 20 explicit nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
21 ~nvdisp_disp0() override; 21 ~nvdisp_disp0() override;
22 22
23 u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 23 u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
24 IoctlCtrl& ctrl) override; 24 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
25 IoctlVersion version) override;
25 26
26 /// Performs a screen flip, drawing the buffer pointed to by the handle. 27 /// Performs a screen flip, drawing the buffer pointed to by the handle.
27 void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, 28 void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride,
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 24ab3f2e9..6bc053f27 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -26,8 +26,9 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_
26 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} 26 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
27nvhost_as_gpu::~nvhost_as_gpu() = default; 27nvhost_as_gpu::~nvhost_as_gpu() = default;
28 28
29u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 29u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
30 IoctlCtrl& ctrl) { 30 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
31 IoctlVersion version) {
31 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 32 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
32 command.raw, input.size(), output.size()); 33 command.raw, input.size(), output.size());
33 34
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 30ca5f4c3..169fb8f0e 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
@@ -20,8 +20,9 @@ public:
20 explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); 20 explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
21 ~nvhost_as_gpu() override; 21 ~nvhost_as_gpu() override;
22 22
23 u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 23 u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
24 IoctlCtrl& ctrl) override; 24 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
25 IoctlVersion version) override;
25 26
26private: 27private:
27 enum class IoctlCommand : u32_le { 28 enum class IoctlCommand : u32_le {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 9a66a5f88..ff6b1abae 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -19,8 +19,9 @@ nvhost_ctrl::nvhost_ctrl(Core::System& system, EventInterface& events_interface)
19 : nvdevice(system), events_interface{events_interface} {} 19 : nvdevice(system), events_interface{events_interface} {}
20nvhost_ctrl::~nvhost_ctrl() = default; 20nvhost_ctrl::~nvhost_ctrl() = default;
21 21
22u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 22u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
23 IoctlCtrl& ctrl) { 23 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
24 IoctlVersion version) {
24 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 25 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
25 command.raw, input.size(), output.size()); 26 command.raw, input.size(), output.size());
26 27
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index 14e6e7e57..9898623de 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -17,8 +17,9 @@ public:
17 explicit nvhost_ctrl(Core::System& system, EventInterface& events_interface); 17 explicit nvhost_ctrl(Core::System& system, EventInterface& events_interface);
18 ~nvhost_ctrl() override; 18 ~nvhost_ctrl() override;
19 19
20 u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 20 u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
21 IoctlCtrl& ctrl) override; 21 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
22 IoctlVersion version) override;
22 23
23private: 24private:
24 enum class IoctlCommand : u32_le { 25 enum class IoctlCommand : u32_le {
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 988effd90..389ace76f 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -15,14 +15,15 @@ namespace Service::Nvidia::Devices {
15nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system) {} 15nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system) {}
16nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default; 16nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default;
17 17
18u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 18u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input,
19 IoctlCtrl& ctrl) { 19 const std::vector<u8>& input2, std::vector<u8>& output,
20 std::vector<u8>& output2, IoctlCtrl& ctrl, IoctlVersion version) {
20 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 21 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
21 command.raw, input.size(), output.size()); 22 command.raw, input.size(), output.size());
22 23
23 switch (static_cast<IoctlCommand>(command.raw)) { 24 switch (static_cast<IoctlCommand>(command.raw)) {
24 case IoctlCommand::IocGetCharacteristicsCommand: 25 case IoctlCommand::IocGetCharacteristicsCommand:
25 return GetCharacteristics(input, output); 26 return GetCharacteristics(input, output, output2, version);
26 case IoctlCommand::IocGetTPCMasksCommand: 27 case IoctlCommand::IocGetTPCMasksCommand:
27 return GetTPCMasks(input, output); 28 return GetTPCMasks(input, output);
28 case IoctlCommand::IocGetActiveSlotMaskCommand: 29 case IoctlCommand::IocGetActiveSlotMaskCommand:
@@ -44,7 +45,8 @@ u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vec
44 return 0; 45 return 0;
45} 46}
46 47
47u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output) { 48u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output,
49 std::vector<u8>& output2, IoctlVersion version) {
48 LOG_DEBUG(Service_NVDRV, "called"); 50 LOG_DEBUG(Service_NVDRV, "called");
49 IoctlCharacteristics params{}; 51 IoctlCharacteristics params{};
50 std::memcpy(&params, input.data(), input.size()); 52 std::memcpy(&params, input.data(), input.size());
@@ -85,7 +87,13 @@ u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vecto
85 params.gc.gr_compbit_store_base_hw = 0x0; 87 params.gc.gr_compbit_store_base_hw = 0x0;
86 params.gpu_characteristics_buf_size = 0xA0; 88 params.gpu_characteristics_buf_size = 0xA0;
87 params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED) 89 params.gpu_characteristics_buf_addr = 0xdeadbeef; // Cannot be 0 (UNUSED)
88 std::memcpy(output.data(), &params, output.size()); 90
91 if (version == IoctlVersion::Version3) {
92 std::memcpy(output.data(), input.data(), output.size());
93 std::memcpy(output2.data(), &params.gc, output2.size());
94 } else {
95 std::memcpy(output.data(), &params, output.size());
96 }
89 return 0; 97 return 0;
90} 98}
91 99
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 2b035ae3f..642b0a2cb 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
@@ -16,8 +16,9 @@ public:
16 explicit nvhost_ctrl_gpu(Core::System& system); 16 explicit nvhost_ctrl_gpu(Core::System& system);
17 ~nvhost_ctrl_gpu() override; 17 ~nvhost_ctrl_gpu() override;
18 18
19 u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 19 u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
20 IoctlCtrl& ctrl) override; 20 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
21 IoctlVersion version) override;
21 22
22private: 23private:
23 enum class IoctlCommand : u32_le { 24 enum class IoctlCommand : u32_le {
@@ -162,7 +163,8 @@ private:
162 }; 163 };
163 static_assert(sizeof(IoctlGetGpuTime) == 8, "IoctlGetGpuTime is incorrect size"); 164 static_assert(sizeof(IoctlGetGpuTime) == 8, "IoctlGetGpuTime is incorrect size");
164 165
165 u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output); 166 u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output,
167 std::vector<u8>& output2, IoctlVersion version);
166 u32 GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output); 168 u32 GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output);
167 u32 GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output); 169 u32 GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output);
168 u32 ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output); 170 u32 ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index b4ee2a255..2b8d1bef6 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -17,8 +17,9 @@ nvhost_gpu::nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev)
17 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} 17 : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
18nvhost_gpu::~nvhost_gpu() = default; 18nvhost_gpu::~nvhost_gpu() = default;
19 19
20u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 20u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
21 IoctlCtrl& ctrl) { 21 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
22 IoctlVersion version) {
22 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 23 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
23 command.raw, input.size(), output.size()); 24 command.raw, input.size(), output.size());
24 25
@@ -50,7 +51,7 @@ u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u
50 return SubmitGPFIFO(input, output); 51 return SubmitGPFIFO(input, output);
51 } 52 }
52 if (command.cmd == NVGPU_IOCTL_CHANNEL_KICKOFF_PB) { 53 if (command.cmd == NVGPU_IOCTL_CHANNEL_KICKOFF_PB) {
53 return KickoffPB(input, output); 54 return KickoffPB(input, output, input2, version);
54 } 55 }
55 } 56 }
56 57
@@ -173,7 +174,8 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp
173 return 0; 174 return 0;
174} 175}
175 176
176u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output) { 177u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output,
178 const std::vector<u8>& input2, IoctlVersion version) {
177 if (input.size() < sizeof(IoctlSubmitGpfifo)) { 179 if (input.size() < sizeof(IoctlSubmitGpfifo)) {
178 UNIMPLEMENTED(); 180 UNIMPLEMENTED();
179 } 181 }
@@ -183,9 +185,13 @@ u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output)
183 params.num_entries, params.flags.raw); 185 params.num_entries, params.flags.raw);
184 186
185 Tegra::CommandList entries(params.num_entries); 187 Tegra::CommandList entries(params.num_entries);
186 Memory::ReadBlock(params.address, entries.data(), 188 if (version == IoctlVersion::Version2) {
187 params.num_entries * sizeof(Tegra::CommandListHeader)); 189 std::memcpy(entries.data(), input2.data(),
188 190 params.num_entries * sizeof(Tegra::CommandListHeader));
191 } else {
192 Memory::ReadBlock(params.address, entries.data(),
193 params.num_entries * sizeof(Tegra::CommandListHeader));
194 }
189 UNIMPLEMENTED_IF(params.flags.add_wait.Value() != 0); 195 UNIMPLEMENTED_IF(params.flags.add_wait.Value() != 0);
190 UNIMPLEMENTED_IF(params.flags.add_increment.Value() != 0); 196 UNIMPLEMENTED_IF(params.flags.add_increment.Value() != 0);
191 197
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index d2e8fbae9..d056dd046 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -24,8 +24,9 @@ public:
24 explicit nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); 24 explicit nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
25 ~nvhost_gpu() override; 25 ~nvhost_gpu() override;
26 26
27 u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 27 u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
28 IoctlCtrl& ctrl) override; 28 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
29 IoctlVersion version) override;
29 30
30private: 31private:
31 enum class IoctlCommand : u32_le { 32 enum class IoctlCommand : u32_le {
@@ -183,7 +184,8 @@ private:
183 u32 AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output); 184 u32 AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output);
184 u32 AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output); 185 u32 AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output);
185 u32 SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& output); 186 u32 SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& output);
186 u32 KickoffPB(const std::vector<u8>& input, std::vector<u8>& output); 187 u32 KickoffPB(const std::vector<u8>& input, std::vector<u8>& output,
188 const std::vector<u8>& input2, IoctlVersion version);
187 u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); 189 u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
188 u32 ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output); 190 u32 ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output);
189 191
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index f572ad30f..bdae8b887 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -13,8 +13,9 @@ namespace Service::Nvidia::Devices {
13nvhost_nvdec::nvhost_nvdec(Core::System& system) : nvdevice(system) {} 13nvhost_nvdec::nvhost_nvdec(Core::System& system) : nvdevice(system) {}
14nvhost_nvdec::~nvhost_nvdec() = default; 14nvhost_nvdec::~nvhost_nvdec() = default;
15 15
16u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 16u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
17 IoctlCtrl& ctrl) { 17 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
18 IoctlVersion version) {
18 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 19 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
19 command.raw, input.size(), output.size()); 20 command.raw, input.size(), output.size());
20 21
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index 2710f0511..cbdac8069 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -16,8 +16,9 @@ public:
16 explicit nvhost_nvdec(Core::System& system); 16 explicit nvhost_nvdec(Core::System& system);
17 ~nvhost_nvdec() override; 17 ~nvhost_nvdec() override;
18 18
19 u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 19 u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
20 IoctlCtrl& ctrl) override; 20 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
21 IoctlVersion version) override;
21 22
22private: 23private:
23 enum class IoctlCommand : u32_le { 24 enum class IoctlCommand : u32_le {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
index 38282956f..96e7b7dab 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.cpp
@@ -13,8 +13,9 @@ namespace Service::Nvidia::Devices {
13nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {} 13nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {}
14nvhost_nvjpg::~nvhost_nvjpg() = default; 14nvhost_nvjpg::~nvhost_nvjpg() = default;
15 15
16u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 16u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
17 IoctlCtrl& ctrl) { 17 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
18 IoctlVersion version) {
18 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 19 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
19 command.raw, input.size(), output.size()); 20 command.raw, input.size(), output.size());
20 21
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
index 379766693..98dcac52f 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvjpg.h
@@ -16,8 +16,9 @@ public:
16 explicit nvhost_nvjpg(Core::System& system); 16 explicit nvhost_nvjpg(Core::System& system);
17 ~nvhost_nvjpg() override; 17 ~nvhost_nvjpg() override;
18 18
19 u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 19 u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
20 IoctlCtrl& ctrl) override; 20 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
21 IoctlVersion version) override;
21 22
22private: 23private:
23 enum class IoctlCommand : u32_le { 24 enum class IoctlCommand : u32_le {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index 70e8091db..c695b8863 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -13,8 +13,9 @@ namespace Service::Nvidia::Devices {
13nvhost_vic::nvhost_vic(Core::System& system) : nvdevice(system) {} 13nvhost_vic::nvhost_vic(Core::System& system) : nvdevice(system) {}
14nvhost_vic::~nvhost_vic() = default; 14nvhost_vic::~nvhost_vic() = default;
15 15
16u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 16u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
17 IoctlCtrl& ctrl) { 17 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
18 IoctlVersion version) {
18 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}", 19 LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
19 command.raw, input.size(), output.size()); 20 command.raw, input.size(), output.size());
20 21
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index 7d111977e..bec32bea1 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -16,8 +16,9 @@ public:
16 explicit nvhost_vic(Core::System& system); 16 explicit nvhost_vic(Core::System& system);
17 ~nvhost_vic() override; 17 ~nvhost_vic() override;
18 18
19 u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 19 u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
20 IoctlCtrl& ctrl) override; 20 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
21 IoctlVersion version) override;
21 22
22private: 23private:
23 enum class IoctlCommand : u32_le { 24 enum class IoctlCommand : u32_le {
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index 223b496b7..8c742316c 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -28,8 +28,9 @@ VAddr nvmap::GetObjectAddress(u32 handle) const {
28 return object->addr; 28 return object->addr;
29} 29}
30 30
31u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 31u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
32 IoctlCtrl& ctrl) { 32 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
33 IoctlVersion version) {
33 switch (static_cast<IoctlCommand>(command.raw)) { 34 switch (static_cast<IoctlCommand>(command.raw)) {
34 case IoctlCommand::Create: 35 case IoctlCommand::Create:
35 return IocCreate(input, output); 36 return IocCreate(input, output);
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h
index bf4a101c2..73c2e8809 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.h
+++ b/src/core/hle/service/nvdrv/devices/nvmap.h
@@ -22,8 +22,9 @@ public:
22 /// Returns the allocated address of an nvmap object given its handle. 22 /// Returns the allocated address of an nvmap object given its handle.
23 VAddr GetObjectAddress(u32 handle) const; 23 VAddr GetObjectAddress(u32 handle) const;
24 24
25 u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, 25 u32 ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
26 IoctlCtrl& ctrl) override; 26 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
27 IoctlVersion version) override;
27 28
28 /// Represents an nvmap object. 29 /// Represents an nvmap object.
29 struct Object { 30 struct Object {
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index d5be64ed2..5e0c23602 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -33,42 +33,77 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) {
33 rb.Push<u32>(0); 33 rb.Push<u32>(0);
34} 34}
35 35
36void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { 36void NVDRV::IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version) {
37 LOG_DEBUG(Service_NVDRV, "called");
38
39 IPC::RequestParser rp{ctx}; 37 IPC::RequestParser rp{ctx};
40 u32 fd = rp.Pop<u32>(); 38 u32 fd = rp.Pop<u32>();
41 u32 command = rp.Pop<u32>(); 39 u32 command = rp.Pop<u32>();
42 40
43 std::vector<u8> output(ctx.GetWriteBufferSize()); 41 /// Ioctl 3 has 2 outputs, first in the input params, second is the result
42 std::vector<u8> output(ctx.GetWriteBufferSize(0));
43 std::vector<u8> output2;
44 if (version == IoctlVersion::Version3) {
45 output2.resize((ctx.GetWriteBufferSize(1)));
46 }
47
48 /// Ioctl2 has 2 inputs. It's used to pass data directly instead of providing a pointer.
49 /// KickOfPB uses this
50 auto input = ctx.ReadBuffer(0);
51
52 std::vector<u8> input2;
53 if (version == IoctlVersion::Version2) {
54 input2 = ctx.ReadBuffer(1);
55 }
44 56
45 IoctlCtrl ctrl{}; 57 IoctlCtrl ctrl{};
46 58
47 u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output, ctrl); 59 u32 result = nvdrv->Ioctl(fd, command, input, input2, output, output2, ctrl, version);
48 60
49 if (ctrl.must_delay) { 61 if (ctrl.must_delay) {
50 ctrl.fresh_call = false; 62 ctrl.fresh_call = false;
51 ctx.SleepClientThread( 63 ctx.SleepClientThread("NVServices::DelayedResponse", ctrl.timeout,
52 "NVServices::DelayedResponse", ctrl.timeout, 64 [=](Kernel::SharedPtr<Kernel::Thread> thread,
53 [=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, 65 Kernel::HLERequestContext& ctx,
54 Kernel::ThreadWakeupReason reason) { 66 Kernel::ThreadWakeupReason reason) {
55 IoctlCtrl ctrl2{ctrl}; 67 IoctlCtrl ctrl2{ctrl};
56 std::vector<u8> output2 = output; 68 std::vector<u8> tmp_output = output;
57 u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output2, ctrl2); 69 std::vector<u8> tmp_output2 = output2;
58 ctx.WriteBuffer(output2); 70 u32 result = nvdrv->Ioctl(fd, command, input, input2, tmp_output,
59 IPC::ResponseBuilder rb{ctx, 3}; 71 tmp_output2, ctrl2, version);
60 rb.Push(RESULT_SUCCESS); 72 ctx.WriteBuffer(tmp_output, 0);
61 rb.Push(result); 73 if (version == IoctlVersion::Version3) {
62 }, 74 ctx.WriteBuffer(tmp_output2, 1);
63 nvdrv->GetEventWriteable(ctrl.event_id)); 75 }
76 IPC::ResponseBuilder rb{ctx, 3};
77 rb.Push(RESULT_SUCCESS);
78 rb.Push(result);
79 },
80 nvdrv->GetEventWriteable(ctrl.event_id));
64 } else { 81 } else {
65 ctx.WriteBuffer(output); 82 ctx.WriteBuffer(output);
83 if (version == IoctlVersion::Version3) {
84 ctx.WriteBuffer(output2, 1);
85 }
66 } 86 }
67 IPC::ResponseBuilder rb{ctx, 3}; 87 IPC::ResponseBuilder rb{ctx, 3};
68 rb.Push(RESULT_SUCCESS); 88 rb.Push(RESULT_SUCCESS);
69 rb.Push(result); 89 rb.Push(result);
70} 90}
71 91
92void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
93 LOG_DEBUG(Service_NVDRV, "called");
94 IoctlBase(ctx, IoctlVersion::Version1);
95}
96
97void NVDRV::Ioctl2(Kernel::HLERequestContext& ctx) {
98 LOG_DEBUG(Service_NVDRV, "called");
99 IoctlBase(ctx, IoctlVersion::Version2);
100}
101
102void NVDRV::Ioctl3(Kernel::HLERequestContext& ctx) {
103 LOG_DEBUG(Service_NVDRV, "called");
104 IoctlBase(ctx, IoctlVersion::Version3);
105}
106
72void NVDRV::Close(Kernel::HLERequestContext& ctx) { 107void NVDRV::Close(Kernel::HLERequestContext& ctx) {
73 LOG_DEBUG(Service_NVDRV, "called"); 108 LOG_DEBUG(Service_NVDRV, "called");
74 109
@@ -154,8 +189,8 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name)
154 {8, &NVDRV::SetClientPID, "SetClientPID"}, 189 {8, &NVDRV::SetClientPID, "SetClientPID"},
155 {9, &NVDRV::DumpGraphicsMemoryInfo, "DumpGraphicsMemoryInfo"}, 190 {9, &NVDRV::DumpGraphicsMemoryInfo, "DumpGraphicsMemoryInfo"},
156 {10, nullptr, "InitializeDevtools"}, 191 {10, nullptr, "InitializeDevtools"},
157 {11, &NVDRV::Ioctl, "Ioctl2"}, 192 {11, &NVDRV::Ioctl2, "Ioctl2"},
158 {12, nullptr, "Ioctl3"}, 193 {12, &NVDRV::Ioctl3, "Ioctl3"},
159 {13, &NVDRV::FinishInitialize, "FinishInitialize"}, 194 {13, &NVDRV::FinishInitialize, "FinishInitialize"},
160 }; 195 };
161 RegisterHandlers(functions); 196 RegisterHandlers(functions);
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h
index 10a0ecd52..9269ce00c 100644
--- a/src/core/hle/service/nvdrv/interface.h
+++ b/src/core/hle/service/nvdrv/interface.h
@@ -24,6 +24,8 @@ public:
24private: 24private:
25 void Open(Kernel::HLERequestContext& ctx); 25 void Open(Kernel::HLERequestContext& ctx);
26 void Ioctl(Kernel::HLERequestContext& ctx); 26 void Ioctl(Kernel::HLERequestContext& ctx);
27 void Ioctl2(Kernel::HLERequestContext& ctx);
28 void Ioctl3(Kernel::HLERequestContext& ctx);
27 void Close(Kernel::HLERequestContext& ctx); 29 void Close(Kernel::HLERequestContext& ctx);
28 void Initialize(Kernel::HLERequestContext& ctx); 30 void Initialize(Kernel::HLERequestContext& ctx);
29 void QueryEvent(Kernel::HLERequestContext& ctx); 31 void QueryEvent(Kernel::HLERequestContext& ctx);
@@ -31,6 +33,7 @@ private:
31 void FinishInitialize(Kernel::HLERequestContext& ctx); 33 void FinishInitialize(Kernel::HLERequestContext& ctx);
32 void GetStatus(Kernel::HLERequestContext& ctx); 34 void GetStatus(Kernel::HLERequestContext& ctx);
33 void DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx); 35 void DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx);
36 void IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version);
34 37
35 std::shared_ptr<Module> nvdrv; 38 std::shared_ptr<Module> nvdrv;
36 39
diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h
index ac03cbc23..529b03471 100644
--- a/src/core/hle/service/nvdrv/nvdata.h
+++ b/src/core/hle/service/nvdrv/nvdata.h
@@ -34,6 +34,12 @@ enum class EventState {
34 Busy = 3, 34 Busy = 3,
35}; 35};
36 36
37enum class IoctlVersion : u32 {
38 Version1,
39 Version2,
40 Version3,
41};
42
37struct IoctlCtrl { 43struct IoctlCtrl {
38 // First call done to the servioce for services that call itself again after a call. 44 // First call done to the servioce for services that call itself again after a call.
39 bool fresh_call{true}; 45 bool fresh_call{true};
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 2011a226a..307a7e928 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -71,13 +71,14 @@ u32 Module::Open(const std::string& device_name) {
71 return fd; 71 return fd;
72} 72}
73 73
74u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output, 74u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, const std::vector<u8>& input2,
75 IoctlCtrl& ctrl) { 75 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
76 IoctlVersion version) {
76 auto itr = open_files.find(fd); 77 auto itr = open_files.find(fd);
77 ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); 78 ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device");
78 79
79 auto& device = itr->second; 80 auto& device = itr->second;
80 return device->ioctl({command}, input, output, ctrl); 81 return device->ioctl({command}, input, input2, output, output2, ctrl, version);
81} 82}
82 83
83ResultCode Module::Close(u32 fd) { 84ResultCode Module::Close(u32 fd) {
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index a339ab672..f8bb28969 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -106,8 +106,9 @@ public:
106 /// Opens a device node and returns a file descriptor to it. 106 /// Opens a device node and returns a file descriptor to it.
107 u32 Open(const std::string& device_name); 107 u32 Open(const std::string& device_name);
108 /// Sends an ioctl command to the specified file descriptor. 108 /// Sends an ioctl command to the specified file descriptor.
109 u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output, 109 u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, const std::vector<u8>& input2,
110 IoctlCtrl& ctrl); 110 std::vector<u8>& output, std::vector<u8>& output2, IoctlCtrl& ctrl,
111 IoctlVersion version);
111 /// Closes a device file descriptor and returns operation success. 112 /// Closes a device file descriptor and returns operation success.
112 ResultCode Close(u32 fd); 113 ResultCode Close(u32 fd);
113 114