diff options
Diffstat (limited to 'src/core')
7 files changed, 47 insertions, 21 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index d8735491c..36970f828 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | |||
| @@ -11,8 +11,9 @@ | |||
| 11 | 11 | ||
| 12 | namespace Service::Nvidia::Devices { | 12 | namespace Service::Nvidia::Devices { |
| 13 | 13 | ||
| 14 | nvhost_nvdec::nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_dev) | 14 | nvhost_nvdec::nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_dev, |
| 15 | : nvhost_nvdec_common(system, std::move(nvmap_dev)) {} | 15 | SyncpointManager& syncpoint_manager) |
| 16 | : nvhost_nvdec_common(system, std::move(nvmap_dev), syncpoint_manager) {} | ||
| 16 | nvhost_nvdec::~nvhost_nvdec() = default; | 17 | nvhost_nvdec::~nvhost_nvdec() = default; |
| 17 | 18 | ||
| 18 | NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input, | 19 | NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input, |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index 79b8b6de1..77ef53cdd 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | |||
| @@ -11,7 +11,8 @@ namespace Service::Nvidia::Devices { | |||
| 11 | 11 | ||
| 12 | class nvhost_nvdec final : public nvhost_nvdec_common { | 12 | class nvhost_nvdec final : public nvhost_nvdec_common { |
| 13 | public: | 13 | public: |
| 14 | explicit nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); | 14 | explicit nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_dev, |
| 15 | SyncpointManager& syncpoint_manager); | ||
| 15 | ~nvhost_nvdec() override; | 16 | ~nvhost_nvdec() override; |
| 16 | 17 | ||
| 17 | NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 18 | NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) 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 b49cecb42..4898dc27a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include "core/core.h" | 11 | #include "core/core.h" |
| 12 | #include "core/hle/service/nvdrv/devices/nvhost_nvdec_common.h" | 12 | #include "core/hle/service/nvdrv/devices/nvhost_nvdec_common.h" |
| 13 | #include "core/hle/service/nvdrv/devices/nvmap.h" | 13 | #include "core/hle/service/nvdrv/devices/nvmap.h" |
| 14 | #include "core/hle/service/nvdrv/syncpoint_manager.h" | ||
| 14 | #include "core/memory.h" | 15 | #include "core/memory.h" |
| 15 | #include "video_core/memory_manager.h" | 16 | #include "video_core/memory_manager.h" |
| 16 | #include "video_core/renderer_base.h" | 17 | #include "video_core/renderer_base.h" |
| @@ -36,8 +37,9 @@ std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::s | |||
| 36 | } | 37 | } |
| 37 | } // Anonymous namespace | 38 | } // Anonymous namespace |
| 38 | 39 | ||
| 39 | nvhost_nvdec_common::nvhost_nvdec_common(Core::System& system, std::shared_ptr<nvmap> nvmap_dev) | 40 | nvhost_nvdec_common::nvhost_nvdec_common(Core::System& system, std::shared_ptr<nvmap> nvmap_dev, |
| 40 | : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} | 41 | SyncpointManager& syncpoint_manager) |
| 42 | : nvdevice(system), nvmap_dev(std::move(nvmap_dev)), syncpoint_manager(syncpoint_manager) {} | ||
| 41 | nvhost_nvdec_common::~nvhost_nvdec_common() = default; | 43 | nvhost_nvdec_common::~nvhost_nvdec_common() = default; |
| 42 | 44 | ||
| 43 | NvResult nvhost_nvdec_common::SetNVMAPfd(const std::vector<u8>& input) { | 45 | NvResult nvhost_nvdec_common::SetNVMAPfd(const std::vector<u8>& input) { |
| @@ -71,10 +73,15 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u | |||
| 71 | offset = SpliceVectors(input, wait_checks, params.syncpoint_count, offset); | 73 | offset = SpliceVectors(input, wait_checks, params.syncpoint_count, offset); |
| 72 | offset = SpliceVectors(input, fences, params.fence_count, offset); | 74 | offset = SpliceVectors(input, fences, params.fence_count, offset); |
| 73 | 75 | ||
| 74 | // TODO(ameerj): For async gpu, utilize fences for syncpoint 'max' increment | ||
| 75 | |||
| 76 | auto& gpu = system.GPU(); | 76 | auto& gpu = system.GPU(); |
| 77 | 77 | if (gpu.UseNvdec()) { | |
| 78 | for (std::size_t i = 0; i < syncpt_increments.size(); i++) { | ||
| 79 | const SyncptIncr& syncpt_incr = syncpt_increments[i]; | ||
| 80 | fences[i].id = syncpt_incr.id; | ||
| 81 | fences[i].value = | ||
| 82 | syncpoint_manager.IncreaseSyncpoint(syncpt_incr.id, syncpt_incr.increments); | ||
| 83 | } | ||
| 84 | } | ||
| 78 | for (const auto& cmd_buffer : command_buffers) { | 85 | for (const auto& cmd_buffer : command_buffers) { |
| 79 | auto object = nvmap_dev->GetObject(cmd_buffer.memory_id); | 86 | auto object = nvmap_dev->GetObject(cmd_buffer.memory_id); |
| 80 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); | 87 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); |
| @@ -89,7 +96,13 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u | |||
| 89 | cmdlist.size() * sizeof(u32)); | 96 | cmdlist.size() * sizeof(u32)); |
| 90 | gpu.PushCommandBuffer(cmdlist); | 97 | gpu.PushCommandBuffer(cmdlist); |
| 91 | } | 98 | } |
| 99 | if (gpu.UseNvdec()) { | ||
| 92 | 100 | ||
| 101 | fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1); | ||
| 102 | |||
| 103 | Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}}; | ||
| 104 | gpu.PushCommandBuffer(cmdlist); | ||
| 105 | } | ||
| 93 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); | 106 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); |
| 94 | // Some games expect command_buffers to be written back | 107 | // Some games expect command_buffers to be written back |
| 95 | offset = sizeof(IoctlSubmit); | 108 | offset = sizeof(IoctlSubmit); |
| @@ -98,6 +111,7 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u | |||
| 98 | offset = WriteVectors(output, reloc_shifts, offset); | 111 | offset = WriteVectors(output, reloc_shifts, offset); |
| 99 | offset = WriteVectors(output, syncpt_increments, offset); | 112 | offset = WriteVectors(output, syncpt_increments, offset); |
| 100 | offset = WriteVectors(output, wait_checks, offset); | 113 | offset = WriteVectors(output, wait_checks, offset); |
| 114 | offset = WriteVectors(output, fences, offset); | ||
| 101 | 115 | ||
| 102 | return NvResult::Success; | 116 | return NvResult::Success; |
| 103 | } | 117 | } |
| @@ -107,9 +121,10 @@ NvResult nvhost_nvdec_common::GetSyncpoint(const std::vector<u8>& input, std::ve | |||
| 107 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); | 121 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); |
| 108 | LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); | 122 | LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); |
| 109 | 123 | ||
| 110 | // We found that implementing this causes deadlocks with async gpu, along with degraded | 124 | if (device_syncpoints[params.param] == 0 && system.GPU().UseNvdec()) { |
| 111 | // performance. TODO: RE the nvdec async implementation | 125 | device_syncpoints[params.param] = syncpoint_manager.AllocateSyncpoint(); |
| 112 | params.value = 0; | 126 | } |
| 127 | params.value = device_syncpoints[params.param]; | ||
| 113 | std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); | 128 | std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); |
| 114 | 129 | ||
| 115 | return NvResult::Success; | 130 | 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 d9f95ba58..4c9d4ba41 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h | |||
| @@ -10,12 +10,16 @@ | |||
| 10 | #include "common/swap.h" | 10 | #include "common/swap.h" |
| 11 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 11 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
| 12 | 12 | ||
| 13 | namespace Service::Nvidia::Devices { | 13 | namespace Service::Nvidia { |
| 14 | class SyncpointManager; | ||
| 15 | |||
| 16 | namespace Devices { | ||
| 14 | class nvmap; | 17 | class nvmap; |
| 15 | 18 | ||
| 16 | class nvhost_nvdec_common : public nvdevice { | 19 | class nvhost_nvdec_common : public nvdevice { |
| 17 | public: | 20 | public: |
| 18 | explicit nvhost_nvdec_common(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); | 21 | explicit nvhost_nvdec_common(Core::System& system, std::shared_ptr<nvmap> nvmap_dev, |
| 22 | SyncpointManager& syncpoint_manager); | ||
| 19 | ~nvhost_nvdec_common() override; | 23 | ~nvhost_nvdec_common() override; |
| 20 | 24 | ||
| 21 | protected: | 25 | protected: |
| @@ -157,8 +161,10 @@ protected: | |||
| 157 | s32_le nvmap_fd{}; | 161 | s32_le nvmap_fd{}; |
| 158 | u32_le submit_timeout{}; | 162 | u32_le submit_timeout{}; |
| 159 | std::shared_ptr<nvmap> nvmap_dev; | 163 | std::shared_ptr<nvmap> nvmap_dev; |
| 160 | 164 | SyncpointManager& syncpoint_manager; | |
| 165 | std::array<u32, MaxSyncPoints> device_syncpoints{}; | ||
| 161 | // This is expected to be ordered, therefore we must use a map, not unordered_map | 166 | // This is expected to be ordered, therefore we must use a map, not unordered_map |
| 162 | std::map<GPUVAddr, BufferMap> buffer_mappings; | 167 | std::map<GPUVAddr, BufferMap> buffer_mappings; |
| 163 | }; | 168 | }; |
| 164 | }; // namespace Service::Nvidia::Devices | 169 | }; // namespace Devices |
| 170 | } // namespace Service::Nvidia | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index 805fe86ae..72499654c 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | |||
| @@ -10,8 +10,9 @@ | |||
| 10 | #include "video_core/renderer_base.h" | 10 | #include "video_core/renderer_base.h" |
| 11 | 11 | ||
| 12 | namespace Service::Nvidia::Devices { | 12 | namespace Service::Nvidia::Devices { |
| 13 | nvhost_vic::nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev) | 13 | nvhost_vic::nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev, |
| 14 | : nvhost_nvdec_common(system, std::move(nvmap_dev)) {} | 14 | SyncpointManager& syncpoint_manager) |
| 15 | : nvhost_nvdec_common(system, std::move(nvmap_dev), syncpoint_manager) {} | ||
| 15 | 16 | ||
| 16 | nvhost_vic::~nvhost_vic() = default; | 17 | nvhost_vic::~nvhost_vic() = default; |
| 17 | 18 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index b2e11f4d4..f401c61fa 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h | |||
| @@ -7,11 +7,11 @@ | |||
| 7 | #include "core/hle/service/nvdrv/devices/nvhost_nvdec_common.h" | 7 | #include "core/hle/service/nvdrv/devices/nvhost_nvdec_common.h" |
| 8 | 8 | ||
| 9 | namespace Service::Nvidia::Devices { | 9 | namespace Service::Nvidia::Devices { |
| 10 | class nvmap; | ||
| 11 | 10 | ||
| 12 | class nvhost_vic final : public nvhost_nvdec_common { | 11 | class nvhost_vic final : public nvhost_nvdec_common { |
| 13 | public: | 12 | public: |
| 14 | explicit nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); | 13 | explicit nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev, |
| 14 | SyncpointManager& syncpoint_manager); | ||
| 15 | ~nvhost_vic(); | 15 | ~nvhost_vic(); |
| 16 | 16 | ||
| 17 | NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 17 | NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index e03195afe..620c18728 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp | |||
| @@ -55,9 +55,11 @@ Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} { | |||
| 55 | devices["/dev/nvdisp_disp0"] = std::make_shared<Devices::nvdisp_disp0>(system, nvmap_dev); | 55 | devices["/dev/nvdisp_disp0"] = std::make_shared<Devices::nvdisp_disp0>(system, nvmap_dev); |
| 56 | devices["/dev/nvhost-ctrl"] = | 56 | devices["/dev/nvhost-ctrl"] = |
| 57 | std::make_shared<Devices::nvhost_ctrl>(system, events_interface, syncpoint_manager); | 57 | std::make_shared<Devices::nvhost_ctrl>(system, events_interface, syncpoint_manager); |
| 58 | devices["/dev/nvhost-nvdec"] = std::make_shared<Devices::nvhost_nvdec>(system, nvmap_dev); | 58 | devices["/dev/nvhost-nvdec"] = |
| 59 | std::make_shared<Devices::nvhost_nvdec>(system, nvmap_dev, syncpoint_manager); | ||
| 59 | devices["/dev/nvhost-nvjpg"] = std::make_shared<Devices::nvhost_nvjpg>(system); | 60 | devices["/dev/nvhost-nvjpg"] = std::make_shared<Devices::nvhost_nvjpg>(system); |
| 60 | devices["/dev/nvhost-vic"] = std::make_shared<Devices::nvhost_vic>(system, nvmap_dev); | 61 | devices["/dev/nvhost-vic"] = |
| 62 | std::make_shared<Devices::nvhost_vic>(system, nvmap_dev, syncpoint_manager); | ||
| 61 | } | 63 | } |
| 62 | 64 | ||
| 63 | Module::~Module() = default; | 65 | Module::~Module() = default; |