diff options
| author | 2020-12-28 01:02:06 -0500 | |
|---|---|---|
| committer | 2021-01-07 14:33:45 -0500 | |
| commit | 2c27127d04a155fe0f893e84263d58f14473785d (patch) | |
| tree | e72b7d973f5c0dd4a553f815a632bf8fcc687998 /src/core | |
| parent | Merge pull request #5306 from MerryMage/ignore-library-Open (diff) | |
| download | yuzu-2c27127d04a155fe0f893e84263d58f14473785d.tar.gz yuzu-2c27127d04a155fe0f893e84263d58f14473785d.tar.xz yuzu-2c27127d04a155fe0f893e84263d58f14473785d.zip | |
nvdec syncpt incorporation
laying the groundwork for async gpu, although this does not fully implement async nvdec operations
Diffstat (limited to 'src/core')
7 files changed, 43 insertions, 20 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..64370ad4c 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,14 @@ 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 | 76 | for (std::size_t i = 0; i < syncpt_increments.size(); i++) { |
| 77 | SyncptIncr syncpt_incr = syncpt_increments[i]; | ||
| 75 | 78 | ||
| 79 | fences[i].id = syncpt_incr.id; | ||
| 80 | fences[i].value = | ||
| 81 | syncpoint_manager.IncreaseSyncpoint(syncpt_incr.id, syncpt_incr.increments); | ||
| 82 | } | ||
| 76 | auto& gpu = system.GPU(); | 83 | auto& gpu = system.GPU(); |
| 77 | |||
| 78 | for (const auto& cmd_buffer : command_buffers) { | 84 | for (const auto& cmd_buffer : command_buffers) { |
| 79 | auto object = nvmap_dev->GetObject(cmd_buffer.memory_id); | 85 | auto object = nvmap_dev->GetObject(cmd_buffer.memory_id); |
| 80 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); | 86 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); |
| @@ -89,6 +95,10 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u | |||
| 89 | cmdlist.size() * sizeof(u32)); | 95 | cmdlist.size() * sizeof(u32)); |
| 90 | gpu.PushCommandBuffer(cmdlist); | 96 | gpu.PushCommandBuffer(cmdlist); |
| 91 | } | 97 | } |
| 98 | fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1); | ||
| 99 | |||
| 100 | Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}}; | ||
| 101 | gpu.PushCommandBuffer(cmdlist); | ||
| 92 | 102 | ||
| 93 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); | 103 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); |
| 94 | // Some games expect command_buffers to be written back | 104 | // Some games expect command_buffers to be written back |
| @@ -98,6 +108,7 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u | |||
| 98 | offset = WriteVectors(output, reloc_shifts, offset); | 108 | offset = WriteVectors(output, reloc_shifts, offset); |
| 99 | offset = WriteVectors(output, syncpt_increments, offset); | 109 | offset = WriteVectors(output, syncpt_increments, offset); |
| 100 | offset = WriteVectors(output, wait_checks, offset); | 110 | offset = WriteVectors(output, wait_checks, offset); |
| 111 | offset = WriteVectors(output, fences, offset); | ||
| 101 | 112 | ||
| 102 | return NvResult::Success; | 113 | return NvResult::Success; |
| 103 | } | 114 | } |
| @@ -107,9 +118,10 @@ NvResult nvhost_nvdec_common::GetSyncpoint(const std::vector<u8>& input, std::ve | |||
| 107 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); | 118 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); |
| 108 | LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); | 119 | LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); |
| 109 | 120 | ||
| 110 | // We found that implementing this causes deadlocks with async gpu, along with degraded | 121 | if (device_syncpoints[params.param] == 0) { |
| 111 | // performance. TODO: RE the nvdec async implementation | 122 | device_syncpoints[params.param] = syncpoint_manager.AllocateSyncpoint(); |
| 112 | params.value = 0; | 123 | } |
| 124 | params.value = device_syncpoints[params.param]; | ||
| 113 | std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); | 125 | std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); |
| 114 | 126 | ||
| 115 | return NvResult::Success; | 127 | 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; |