diff options
| author | 2021-11-05 15:52:31 +0100 | |
|---|---|---|
| committer | 2022-10-06 21:00:51 +0200 | |
| commit | 139ea93512aeead8a4aee3910a3de86eb109a838 (patch) | |
| tree | 857643fc08617b7035656a51728c399f30c8c2cb /src/video_core/control | |
| parent | NVASGPU: Fix Remap. (diff) | |
| download | yuzu-139ea93512aeead8a4aee3910a3de86eb109a838.tar.gz yuzu-139ea93512aeead8a4aee3910a3de86eb109a838.tar.xz yuzu-139ea93512aeead8a4aee3910a3de86eb109a838.zip | |
VideoCore: implement channels on gpu caches.
Diffstat (limited to 'src/video_core/control')
| -rw-r--r-- | src/video_core/control/channel_state.cpp | 44 | ||||
| -rw-r--r-- | src/video_core/control/channel_state.h | 69 | ||||
| -rw-r--r-- | src/video_core/control/channel_state_cache.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/control/channel_state_cache.h | 68 | ||||
| -rw-r--r-- | src/video_core/control/channel_state_cache.inc | 64 | ||||
| -rw-r--r-- | src/video_core/control/scheduler.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/control/scheduler.h | 38 |
7 files changed, 319 insertions, 0 deletions
diff --git a/src/video_core/control/channel_state.cpp b/src/video_core/control/channel_state.cpp new file mode 100644 index 000000000..67803fe94 --- /dev/null +++ b/src/video_core/control/channel_state.cpp | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/assert.h" | ||
| 6 | #include "video_core/control/channel_state.h" | ||
| 7 | #include "video_core/dma_pusher.h" | ||
| 8 | #include "video_core/engines/fermi_2d.h" | ||
| 9 | #include "video_core/engines/kepler_compute.h" | ||
| 10 | #include "video_core/engines/kepler_memory.h" | ||
| 11 | #include "video_core/engines/maxwell_3d.h" | ||
| 12 | #include "video_core/engines/maxwell_dma.h" | ||
| 13 | #include "video_core/engines/puller.h" | ||
| 14 | #include "video_core/memory_manager.h" | ||
| 15 | |||
| 16 | namespace Tegra::Control { | ||
| 17 | |||
| 18 | ChannelState::ChannelState(s32 bind_id_) { | ||
| 19 | bind_id = bind_id_; | ||
| 20 | initiated = false; | ||
| 21 | } | ||
| 22 | |||
| 23 | void ChannelState::Init(Core::System& system, GPU& gpu) { | ||
| 24 | ASSERT(memory_manager); | ||
| 25 | dma_pusher = std::make_unique<Tegra::DmaPusher>(system, gpu, *memory_manager, *this); | ||
| 26 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, *memory_manager); | ||
| 27 | fermi_2d = std::make_unique<Engines::Fermi2D>(); | ||
| 28 | kepler_compute = std::make_unique<Engines::KeplerCompute>(system, *memory_manager); | ||
| 29 | maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, *memory_manager); | ||
| 30 | kepler_memory = std::make_unique<Engines::KeplerMemory>(system, *memory_manager); | ||
| 31 | initiated = true; | ||
| 32 | } | ||
| 33 | |||
| 34 | void ChannelState::BindRasterizer(VideoCore::RasterizerInterface* rasterizer) { | ||
| 35 | dma_pusher->BindRasterizer(rasterizer); | ||
| 36 | memory_manager->BindRasterizer(rasterizer); | ||
| 37 | maxwell_3d->BindRasterizer(rasterizer); | ||
| 38 | fermi_2d->BindRasterizer(rasterizer); | ||
| 39 | kepler_memory->BindRasterizer(rasterizer); | ||
| 40 | kepler_compute->BindRasterizer(rasterizer); | ||
| 41 | maxwell_dma->BindRasterizer(rasterizer); | ||
| 42 | } | ||
| 43 | |||
| 44 | } // namespace Tegra::Control | ||
diff --git a/src/video_core/control/channel_state.h b/src/video_core/control/channel_state.h new file mode 100644 index 000000000..82808a6b8 --- /dev/null +++ b/src/video_core/control/channel_state.h | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | |||
| 9 | #include "common/common_types.h" | ||
| 10 | |||
| 11 | namespace Core { | ||
| 12 | class System; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace VideoCore { | ||
| 16 | class RasterizerInterface; | ||
| 17 | } | ||
| 18 | |||
| 19 | namespace Tegra { | ||
| 20 | |||
| 21 | class GPU; | ||
| 22 | |||
| 23 | namespace Engines { | ||
| 24 | class Puller; | ||
| 25 | class Fermi2D; | ||
| 26 | class Maxwell3D; | ||
| 27 | class MaxwellDMA; | ||
| 28 | class KeplerCompute; | ||
| 29 | class KeplerMemory; | ||
| 30 | } // namespace Engines | ||
| 31 | |||
| 32 | class MemoryManager; | ||
| 33 | class DmaPusher; | ||
| 34 | |||
| 35 | namespace Control { | ||
| 36 | |||
| 37 | struct ChannelState { | ||
| 38 | ChannelState(s32 bind_id); | ||
| 39 | ChannelState(const ChannelState& state) = delete; | ||
| 40 | ChannelState& operator=(const ChannelState&) = delete; | ||
| 41 | ChannelState(ChannelState&& other) noexcept = default; | ||
| 42 | ChannelState& operator=(ChannelState&& other) noexcept = default; | ||
| 43 | |||
| 44 | void Init(Core::System& system, GPU& gpu); | ||
| 45 | |||
| 46 | void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); | ||
| 47 | |||
| 48 | s32 bind_id = -1; | ||
| 49 | /// 3D engine | ||
| 50 | std::unique_ptr<Engines::Maxwell3D> maxwell_3d; | ||
| 51 | /// 2D engine | ||
| 52 | std::unique_ptr<Engines::Fermi2D> fermi_2d; | ||
| 53 | /// Compute engine | ||
| 54 | std::unique_ptr<Engines::KeplerCompute> kepler_compute; | ||
| 55 | /// DMA engine | ||
| 56 | std::unique_ptr<Engines::MaxwellDMA> maxwell_dma; | ||
| 57 | /// Inline memory engine | ||
| 58 | std::unique_ptr<Engines::KeplerMemory> kepler_memory; | ||
| 59 | |||
| 60 | std::shared_ptr<MemoryManager> memory_manager; | ||
| 61 | |||
| 62 | std::unique_ptr<DmaPusher> dma_pusher; | ||
| 63 | |||
| 64 | bool initiated{}; | ||
| 65 | }; | ||
| 66 | |||
| 67 | } // namespace Control | ||
| 68 | |||
| 69 | } // namespace Tegra | ||
diff --git a/src/video_core/control/channel_state_cache.cpp b/src/video_core/control/channel_state_cache.cpp new file mode 100644 index 000000000..f72a97b2f --- /dev/null +++ b/src/video_core/control/channel_state_cache.cpp | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | #include "video_core/control/channel_state_cache.inc" | ||
| 2 | |||
| 3 | namespace VideoCommon { | ||
| 4 | template class VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo>; | ||
| 5 | } | ||
diff --git a/src/video_core/control/channel_state_cache.h b/src/video_core/control/channel_state_cache.h new file mode 100644 index 000000000..c8298c003 --- /dev/null +++ b/src/video_core/control/channel_state_cache.h | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <deque> | ||
| 4 | #include <limits> | ||
| 5 | #include <unordered_map> | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | namespace Tegra { | ||
| 10 | |||
| 11 | namespace Engines { | ||
| 12 | class Maxwell3D; | ||
| 13 | class KeplerCompute; | ||
| 14 | } // namespace Engines | ||
| 15 | |||
| 16 | class MemoryManager; | ||
| 17 | |||
| 18 | namespace Control { | ||
| 19 | struct ChannelState; | ||
| 20 | } | ||
| 21 | |||
| 22 | } // namespace Tegra | ||
| 23 | |||
| 24 | namespace VideoCommon { | ||
| 25 | |||
| 26 | class ChannelInfo { | ||
| 27 | public: | ||
| 28 | ChannelInfo() = delete; | ||
| 29 | ChannelInfo(Tegra::Control::ChannelState& state); | ||
| 30 | ChannelInfo(const ChannelInfo& state) = delete; | ||
| 31 | ChannelInfo& operator=(const ChannelInfo&) = delete; | ||
| 32 | ChannelInfo(ChannelInfo&& other) = default; | ||
| 33 | ChannelInfo& operator=(ChannelInfo&& other) = default; | ||
| 34 | |||
| 35 | Tegra::Engines::Maxwell3D& maxwell3d; | ||
| 36 | Tegra::Engines::KeplerCompute& kepler_compute; | ||
| 37 | Tegra::MemoryManager& gpu_memory; | ||
| 38 | }; | ||
| 39 | |||
| 40 | template <class P> | ||
| 41 | class ChannelSetupCaches { | ||
| 42 | public: | ||
| 43 | /// Operations for seting the channel of execution. | ||
| 44 | |||
| 45 | /// Create channel state. | ||
| 46 | void CreateChannel(Tegra::Control::ChannelState& channel); | ||
| 47 | |||
| 48 | /// Bind a channel for execution. | ||
| 49 | void BindToChannel(s32 id); | ||
| 50 | |||
| 51 | /// Erase channel's state. | ||
| 52 | void EraseChannel(s32 id); | ||
| 53 | |||
| 54 | protected: | ||
| 55 | static constexpr size_t UNSET_CHANNEL{std::numeric_limits<size_t>::max()}; | ||
| 56 | |||
| 57 | std::deque<P> channel_storage; | ||
| 58 | std::deque<size_t> free_channel_ids; | ||
| 59 | std::unordered_map<s32, size_t> channel_map; | ||
| 60 | |||
| 61 | P* channel_state; | ||
| 62 | size_t current_channel_id{UNSET_CHANNEL}; | ||
| 63 | Tegra::Engines::Maxwell3D* maxwell3d; | ||
| 64 | Tegra::Engines::KeplerCompute* kepler_compute; | ||
| 65 | Tegra::MemoryManager* gpu_memory; | ||
| 66 | }; | ||
| 67 | |||
| 68 | } // namespace VideoCommon | ||
diff --git a/src/video_core/control/channel_state_cache.inc b/src/video_core/control/channel_state_cache.inc new file mode 100644 index 000000000..3eb73af9f --- /dev/null +++ b/src/video_core/control/channel_state_cache.inc | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | #include "video_core/control/channel_state.h" | ||
| 2 | #include "video_core/control/channel_state_cache.h" | ||
| 3 | #include "video_core/engines/kepler_compute.h" | ||
| 4 | #include "video_core/engines/maxwell_3d.h" | ||
| 5 | #include "video_core/memory_manager.h" | ||
| 6 | |||
| 7 | namespace VideoCommon { | ||
| 8 | |||
| 9 | ChannelInfo::ChannelInfo(Tegra::Control::ChannelState& channel_state) | ||
| 10 | : maxwell3d{*channel_state.maxwell_3d}, kepler_compute{*channel_state.kepler_compute}, | ||
| 11 | gpu_memory{*channel_state.memory_manager} {} | ||
| 12 | |||
| 13 | template <class P> | ||
| 14 | void ChannelSetupCaches<P>::CreateChannel(struct Tegra::Control::ChannelState& channel) { | ||
| 15 | ASSERT(channel_map.find(channel.bind_id) == channel_map.end() && channel.bind_id >= 0); | ||
| 16 | auto new_id = [this, &channel]() { | ||
| 17 | if (!free_channel_ids.empty()) { | ||
| 18 | auto id = free_channel_ids.front(); | ||
| 19 | free_channel_ids.pop_front(); | ||
| 20 | new (&channel_storage[id]) ChannelInfo(channel); | ||
| 21 | return id; | ||
| 22 | } | ||
| 23 | channel_storage.emplace_back(channel); | ||
| 24 | return channel_storage.size() - 1; | ||
| 25 | }(); | ||
| 26 | channel_map.emplace(channel.bind_id, new_id); | ||
| 27 | if (current_channel_id != UNSET_CHANNEL) { | ||
| 28 | channel_state = &channel_storage[current_channel_id]; | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | /// Bind a channel for execution. | ||
| 33 | template <class P> | ||
| 34 | void ChannelSetupCaches<P>::BindToChannel(s32 id) { | ||
| 35 | auto it = channel_map.find(id); | ||
| 36 | ASSERT(it != channel_map.end() && id >= 0); | ||
| 37 | current_channel_id = it->second; | ||
| 38 | channel_state = &channel_storage[current_channel_id]; | ||
| 39 | maxwell3d = &channel_state->maxwell3d; | ||
| 40 | kepler_compute = &channel_state->kepler_compute; | ||
| 41 | gpu_memory = &channel_state->gpu_memory; | ||
| 42 | } | ||
| 43 | |||
| 44 | /// Erase channel's channel_state. | ||
| 45 | template <class P> | ||
| 46 | void ChannelSetupCaches<P>::EraseChannel(s32 id) { | ||
| 47 | const auto it = channel_map.find(id); | ||
| 48 | ASSERT(it != channel_map.end() && id >= 0); | ||
| 49 | const auto this_id = it->second; | ||
| 50 | free_channel_ids.push_back(this_id); | ||
| 51 | channel_map.erase(it); | ||
| 52 | if (this_id == current_channel_id) { | ||
| 53 | current_channel_id = UNSET_CHANNEL; | ||
| 54 | channel_state = nullptr; | ||
| 55 | maxwell3d = nullptr; | ||
| 56 | kepler_compute = nullptr; | ||
| 57 | gpu_memory = nullptr; | ||
| 58 | } else if (current_channel_id != UNSET_CHANNEL) { | ||
| 59 | channel_state = &channel_storage[current_channel_id]; | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | |||
| 64 | } // namespace VideoCommon | ||
diff --git a/src/video_core/control/scheduler.cpp b/src/video_core/control/scheduler.cpp new file mode 100644 index 000000000..e1abcb188 --- /dev/null +++ b/src/video_core/control/scheduler.cpp | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "video_core/control/channel_state.h" | ||
| 8 | #include "video_core/control/scheduler.h" | ||
| 9 | #include "video_core/gpu.h" | ||
| 10 | |||
| 11 | namespace Tegra::Control { | ||
| 12 | Scheduler::Scheduler(GPU& gpu_) : gpu{gpu_} {} | ||
| 13 | |||
| 14 | Scheduler::~Scheduler() = default; | ||
| 15 | |||
| 16 | void Scheduler::Push(s32 channel, CommandList&& entries) { | ||
| 17 | std::unique_lock<std::mutex> lk(scheduling_guard); | ||
| 18 | auto it = channels.find(channel); | ||
| 19 | auto channel_state = it->second; | ||
| 20 | gpu.BindChannel(channel_state->bind_id); | ||
| 21 | channel_state->dma_pusher->Push(std::move(entries)); | ||
| 22 | channel_state->dma_pusher->DispatchCalls(); | ||
| 23 | } | ||
| 24 | |||
| 25 | void Scheduler::DeclareChannel(std::shared_ptr<ChannelState> new_channel) { | ||
| 26 | s32 channel = new_channel->bind_id; | ||
| 27 | std::unique_lock<std::mutex> lk(scheduling_guard); | ||
| 28 | channels.emplace(channel, new_channel); | ||
| 29 | } | ||
| 30 | |||
| 31 | } // namespace Tegra::Control | ||
diff --git a/src/video_core/control/scheduler.h b/src/video_core/control/scheduler.h new file mode 100644 index 000000000..802e9caff --- /dev/null +++ b/src/video_core/control/scheduler.h | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <mutex> | ||
| 9 | #include <unordered_map> | ||
| 10 | |||
| 11 | #include "video_core/dma_pusher.h" | ||
| 12 | |||
| 13 | namespace Tegra { | ||
| 14 | |||
| 15 | class GPU; | ||
| 16 | |||
| 17 | namespace Control { | ||
| 18 | |||
| 19 | struct ChannelState; | ||
| 20 | |||
| 21 | class Scheduler { | ||
| 22 | public: | ||
| 23 | Scheduler(GPU& gpu_); | ||
| 24 | ~Scheduler(); | ||
| 25 | |||
| 26 | void Push(s32 channel, CommandList&& entries); | ||
| 27 | |||
| 28 | void DeclareChannel(std::shared_ptr<ChannelState> new_channel); | ||
| 29 | |||
| 30 | private: | ||
| 31 | std::unordered_map<s32, std::shared_ptr<ChannelState>> channels; | ||
| 32 | std::mutex scheduling_guard; | ||
| 33 | GPU& gpu; | ||
| 34 | }; | ||
| 35 | |||
| 36 | } // namespace Control | ||
| 37 | |||
| 38 | } // namespace Tegra | ||