summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp100
1 files changed, 26 insertions, 74 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index fcb612864..b6df48360 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -2,15 +2,17 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <cstring>
-
#include "common/assert.h"
#include "common/logging/log.h"
+#include "core/core.h"
#include "core/hle/service/nvdrv/devices/nvhost_nvdec.h"
+#include "video_core/memory_manager.h"
+#include "video_core/renderer_base.h"
namespace Service::Nvidia::Devices {
-nvhost_nvdec::nvhost_nvdec(Core::System& system) : nvdevice(system) {}
+nvhost_nvdec::nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_dev)
+ : nvhost_nvdec_common(system, std::move(nvmap_dev)) {}
nvhost_nvdec::~nvhost_nvdec() = default;
u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::vector<u8>& input2,
@@ -21,7 +23,7 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
switch (static_cast<IoctlCommand>(command.raw)) {
case IoctlCommand::IocSetNVMAPfdCommand:
- return SetNVMAPfd(input, output);
+ return SetNVMAPfd(input);
case IoctlCommand::IocSubmit:
return Submit(input, output);
case IoctlCommand::IocGetSyncpoint:
@@ -29,79 +31,29 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std::
case IoctlCommand::IocGetWaitbase:
return GetWaitbase(input, output);
case IoctlCommand::IocMapBuffer:
- return MapBuffer(input, output);
+ case IoctlCommand::IocMapBuffer2:
+ case IoctlCommand::IocMapBuffer3:
case IoctlCommand::IocMapBufferEx:
- return MapBufferEx(input, output);
- case IoctlCommand::IocUnmapBufferEx:
- return UnmapBufferEx(input, output);
+ return MapBuffer(input, output);
+ case IoctlCommand::IocUnmapBufferEx: {
+ // This command is sent when the video stream has ended, flush all video contexts
+ // This is usually sent in the folowing order: vic, nvdec, vic.
+ // Inform the GPU to clear any remaining nvdec buffers when this is detected.
+ LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
+ Tegra::ChCommandHeaderList cmdlist(1);
+ cmdlist[0] = Tegra::ChCommandHeader{0xDEADB33F};
+ system.GPU().PushCommandBuffer(cmdlist);
+ [[fallthrough]]; // fallthrough to unmap buffers
+ };
+ case IoctlCommand::IocUnmapBuffer:
+ case IoctlCommand::IocUnmapBuffer2:
+ case IoctlCommand::IocUnmapBuffer3:
+ return UnmapBuffer(input, output);
+ case IoctlCommand::IocSetSubmitTimeout:
+ return SetSubmitTimeout(input, output);
}
- UNIMPLEMENTED_MSG("Unimplemented ioctl");
- return 0;
-}
-
-u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
- IoctlSetNvmapFD params{};
- std::memcpy(&params, input.data(), sizeof(IoctlSetNvmapFD));
- LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
-
- nvmap_fd = params.nvmap_fd;
- return 0;
-}
-
-u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
- IoctlSubmit params{};
- std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
- LOG_WARNING(Service_NVDRV, "(STUBBED) called");
- std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
- return 0;
-}
-
-u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
- IoctlGetSyncpoint params{};
- std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
- LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
- params.value = 0; // Seems to be hard coded at 0
- std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
- return 0;
-}
-
-u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
- IoctlGetWaitbase params{};
- std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
- LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
- params.value = 0; // Seems to be hard coded at 0
- std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
- return 0;
-}
-
-u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
- IoctlMapBuffer params{};
- std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
- LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
- params.address_1);
- params.address_1 = 0;
- params.address_2 = 0;
- std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
- return 0;
-}
-
-u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
- IoctlMapBufferEx params{};
- std::memcpy(&params, input.data(), sizeof(IoctlMapBufferEx));
- LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
- params.address_1);
- params.address_1 = 0;
- params.address_2 = 0;
- std::memcpy(output.data(), &params, sizeof(IoctlMapBufferEx));
- return 0;
-}
-
-u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
- IoctlUnmapBufferEx params{};
- std::memcpy(&params, input.data(), sizeof(IoctlUnmapBufferEx));
- LOG_WARNING(Service_NVDRV, "(STUBBED) called");
- std::memcpy(output.data(), &params, sizeof(IoctlUnmapBufferEx));
+ UNIMPLEMENTED_MSG("Unimplemented ioctl 0x{:X}", command.raw);
return 0;
}