summaryrefslogtreecommitdiff
path: root/src/video_core/control
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/control')
-rw-r--r--src/video_core/control/channel_state.cpp40
-rw-r--r--src/video_core/control/channel_state.h68
-rw-r--r--src/video_core/control/channel_state_cache.cpp14
-rw-r--r--src/video_core/control/channel_state_cache.h101
-rw-r--r--src/video_core/control/channel_state_cache.inc86
-rw-r--r--src/video_core/control/scheduler.cpp32
-rw-r--r--src/video_core/control/scheduler.h37
7 files changed, 378 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..cdecc3a91
--- /dev/null
+++ b/src/video_core/control/channel_state.cpp
@@ -0,0 +1,40 @@
1// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "common/assert.h"
5#include "video_core/control/channel_state.h"
6#include "video_core/dma_pusher.h"
7#include "video_core/engines/fermi_2d.h"
8#include "video_core/engines/kepler_compute.h"
9#include "video_core/engines/kepler_memory.h"
10#include "video_core/engines/maxwell_3d.h"
11#include "video_core/engines/maxwell_dma.h"
12#include "video_core/engines/puller.h"
13#include "video_core/memory_manager.h"
14
15namespace Tegra::Control {
16
17ChannelState::ChannelState(s32 bind_id_) : bind_id{bind_id_}, initialized{} {}
18
19void ChannelState::Init(Core::System& system, GPU& gpu) {
20 ASSERT(memory_manager);
21 dma_pusher = std::make_unique<Tegra::DmaPusher>(system, gpu, *memory_manager, *this);
22 maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, *memory_manager);
23 fermi_2d = std::make_unique<Engines::Fermi2D>();
24 kepler_compute = std::make_unique<Engines::KeplerCompute>(system, *memory_manager);
25 maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, *memory_manager);
26 kepler_memory = std::make_unique<Engines::KeplerMemory>(system, *memory_manager);
27 initialized = true;
28}
29
30void ChannelState::BindRasterizer(VideoCore::RasterizerInterface* rasterizer) {
31 dma_pusher->BindRasterizer(rasterizer);
32 memory_manager->BindRasterizer(rasterizer);
33 maxwell_3d->BindRasterizer(rasterizer);
34 fermi_2d->BindRasterizer(rasterizer);
35 kepler_memory->BindRasterizer(rasterizer);
36 kepler_compute->BindRasterizer(rasterizer);
37 maxwell_dma->BindRasterizer(rasterizer);
38}
39
40} // 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..3a7b9872c
--- /dev/null
+++ b/src/video_core/control/channel_state.h
@@ -0,0 +1,68 @@
1// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include <memory>
7
8#include "common/common_types.h"
9
10namespace Core {
11class System;
12}
13
14namespace VideoCore {
15class RasterizerInterface;
16}
17
18namespace Tegra {
19
20class GPU;
21
22namespace Engines {
23class Puller;
24class Fermi2D;
25class Maxwell3D;
26class MaxwellDMA;
27class KeplerCompute;
28class KeplerMemory;
29} // namespace Engines
30
31class MemoryManager;
32class DmaPusher;
33
34namespace Control {
35
36struct ChannelState {
37 explicit ChannelState(s32 bind_id);
38 ChannelState(const ChannelState& state) = delete;
39 ChannelState& operator=(const ChannelState&) = delete;
40 ChannelState(ChannelState&& other) noexcept = default;
41 ChannelState& operator=(ChannelState&& other) noexcept = default;
42
43 void Init(Core::System& system, GPU& gpu);
44
45 void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
46
47 s32 bind_id = -1;
48 /// 3D engine
49 std::unique_ptr<Engines::Maxwell3D> maxwell_3d;
50 /// 2D engine
51 std::unique_ptr<Engines::Fermi2D> fermi_2d;
52 /// Compute engine
53 std::unique_ptr<Engines::KeplerCompute> kepler_compute;
54 /// DMA engine
55 std::unique_ptr<Engines::MaxwellDMA> maxwell_dma;
56 /// Inline memory engine
57 std::unique_ptr<Engines::KeplerMemory> kepler_memory;
58
59 std::shared_ptr<MemoryManager> memory_manager;
60
61 std::unique_ptr<DmaPusher> dma_pusher;
62
63 bool initialized{};
64};
65
66} // namespace Control
67
68} // 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..4ebeb6356
--- /dev/null
+++ b/src/video_core/control/channel_state_cache.cpp
@@ -0,0 +1,14 @@
1// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "video_core/control/channel_state_cache.inc"
5
6namespace VideoCommon {
7
8ChannelInfo::ChannelInfo(Tegra::Control::ChannelState& channel_state)
9 : maxwell3d{*channel_state.maxwell_3d}, kepler_compute{*channel_state.kepler_compute},
10 gpu_memory{*channel_state.memory_manager} {}
11
12template class VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo>;
13
14} // namespace VideoCommon
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..584a0c26c
--- /dev/null
+++ b/src/video_core/control/channel_state_cache.h
@@ -0,0 +1,101 @@
1// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include <deque>
7#include <limits>
8#include <mutex>
9#include <optional>
10#include <unordered_map>
11#include <vector>
12
13#include "common/common_types.h"
14
15namespace Tegra {
16
17namespace Engines {
18class Maxwell3D;
19class KeplerCompute;
20} // namespace Engines
21
22class MemoryManager;
23
24namespace Control {
25struct ChannelState;
26}
27
28} // namespace Tegra
29
30namespace VideoCommon {
31
32class ChannelInfo {
33public:
34 ChannelInfo() = delete;
35 explicit ChannelInfo(Tegra::Control::ChannelState& state);
36 ChannelInfo(const ChannelInfo& state) = delete;
37 ChannelInfo& operator=(const ChannelInfo&) = delete;
38 ChannelInfo(ChannelInfo&& other) = default;
39 ChannelInfo& operator=(ChannelInfo&& other) = default;
40
41 Tegra::Engines::Maxwell3D& maxwell3d;
42 Tegra::Engines::KeplerCompute& kepler_compute;
43 Tegra::MemoryManager& gpu_memory;
44};
45
46template <class P>
47class ChannelSetupCaches {
48public:
49 /// Operations for seting the channel of execution.
50 virtual ~ChannelSetupCaches();
51
52 /// Create channel state.
53 virtual void CreateChannel(Tegra::Control::ChannelState& channel);
54
55 /// Bind a channel for execution.
56 void BindToChannel(s32 id);
57
58 /// Erase channel's state.
59 void EraseChannel(s32 id);
60
61 Tegra::MemoryManager* GetFromID(size_t id) const {
62 std::unique_lock<std::mutex> lk(config_mutex);
63 const auto ref = address_spaces.find(id);
64 return ref->second.gpu_memory;
65 }
66
67 std::optional<size_t> getStorageID(size_t id) const {
68 std::unique_lock<std::mutex> lk(config_mutex);
69 const auto ref = address_spaces.find(id);
70 if (ref == address_spaces.end()) {
71 return std::nullopt;
72 }
73 return ref->second.storage_id;
74 }
75
76protected:
77 static constexpr size_t UNSET_CHANNEL{std::numeric_limits<size_t>::max()};
78
79 P* channel_state;
80 size_t current_channel_id{UNSET_CHANNEL};
81 size_t current_address_space{};
82 Tegra::Engines::Maxwell3D* maxwell3d;
83 Tegra::Engines::KeplerCompute* kepler_compute;
84 Tegra::MemoryManager* gpu_memory;
85
86 std::deque<P> channel_storage;
87 std::deque<size_t> free_channel_ids;
88 std::unordered_map<s32, size_t> channel_map;
89 std::vector<size_t> active_channel_ids;
90 struct AddresSpaceRef {
91 size_t ref_count;
92 size_t storage_id;
93 Tegra::MemoryManager* gpu_memory;
94 };
95 std::unordered_map<size_t, AddresSpaceRef> address_spaces;
96 mutable std::mutex config_mutex;
97
98 virtual void OnGPUASRegister([[maybe_unused]] size_t map_id) {}
99};
100
101} // 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..460313893
--- /dev/null
+++ b/src/video_core/control/channel_state_cache.inc
@@ -0,0 +1,86 @@
1// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include <algorithm>
5
6#include "video_core/control/channel_state.h"
7#include "video_core/control/channel_state_cache.h"
8#include "video_core/engines/kepler_compute.h"
9#include "video_core/engines/maxwell_3d.h"
10#include "video_core/memory_manager.h"
11
12namespace VideoCommon {
13
14template <class P>
15ChannelSetupCaches<P>::~ChannelSetupCaches() = default;
16
17template <class P>
18void ChannelSetupCaches<P>::CreateChannel(struct Tegra::Control::ChannelState& channel) {
19 std::unique_lock<std::mutex> lk(config_mutex);
20 ASSERT(channel_map.find(channel.bind_id) == channel_map.end() && channel.bind_id >= 0);
21 auto new_id = [this, &channel]() {
22 if (!free_channel_ids.empty()) {
23 auto id = free_channel_ids.front();
24 free_channel_ids.pop_front();
25 new (&channel_storage[id]) P(channel);
26 return id;
27 }
28 channel_storage.emplace_back(channel);
29 return channel_storage.size() - 1;
30 }();
31 channel_map.emplace(channel.bind_id, new_id);
32 if (current_channel_id != UNSET_CHANNEL) {
33 channel_state = &channel_storage[current_channel_id];
34 }
35 active_channel_ids.push_back(new_id);
36 auto as_it = address_spaces.find(channel.memory_manager->GetID());
37 if (as_it != address_spaces.end()) {
38 as_it->second.ref_count++;
39 return;
40 }
41 AddresSpaceRef new_gpu_mem_ref{
42 .ref_count = 1,
43 .storage_id = address_spaces.size(),
44 .gpu_memory = channel.memory_manager.get(),
45 };
46 address_spaces.emplace(channel.memory_manager->GetID(), new_gpu_mem_ref);
47 OnGPUASRegister(channel.memory_manager->GetID());
48}
49
50/// Bind a channel for execution.
51template <class P>
52void ChannelSetupCaches<P>::BindToChannel(s32 id) {
53 std::unique_lock<std::mutex> lk(config_mutex);
54 auto it = channel_map.find(id);
55 ASSERT(it != channel_map.end() && id >= 0);
56 current_channel_id = it->second;
57 channel_state = &channel_storage[current_channel_id];
58 maxwell3d = &channel_state->maxwell3d;
59 kepler_compute = &channel_state->kepler_compute;
60 gpu_memory = &channel_state->gpu_memory;
61 current_address_space = gpu_memory->GetID();
62}
63
64/// Erase channel's channel_state.
65template <class P>
66void ChannelSetupCaches<P>::EraseChannel(s32 id) {
67 std::unique_lock<std::mutex> lk(config_mutex);
68 const auto it = channel_map.find(id);
69 ASSERT(it != channel_map.end() && id >= 0);
70 const auto this_id = it->second;
71 free_channel_ids.push_back(this_id);
72 channel_map.erase(it);
73 if (this_id == current_channel_id) {
74 current_channel_id = UNSET_CHANNEL;
75 channel_state = nullptr;
76 maxwell3d = nullptr;
77 kepler_compute = nullptr;
78 gpu_memory = nullptr;
79 } else if (current_channel_id != UNSET_CHANNEL) {
80 channel_state = &channel_storage[current_channel_id];
81 }
82 active_channel_ids.erase(
83 std::find(active_channel_ids.begin(), active_channel_ids.end(), this_id));
84}
85
86} // namespace VideoCommon
diff --git a/src/video_core/control/scheduler.cpp b/src/video_core/control/scheduler.cpp
new file mode 100644
index 000000000..f7cbe204e
--- /dev/null
+++ b/src/video_core/control/scheduler.cpp
@@ -0,0 +1,32 @@
1// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include <memory>
5
6#include "common/assert.h"
7#include "video_core/control/channel_state.h"
8#include "video_core/control/scheduler.h"
9#include "video_core/gpu.h"
10
11namespace Tegra::Control {
12Scheduler::Scheduler(GPU& gpu_) : gpu{gpu_} {}
13
14Scheduler::~Scheduler() = default;
15
16void Scheduler::Push(s32 channel, CommandList&& entries) {
17 std::unique_lock lk(scheduling_guard);
18 auto it = channels.find(channel);
19 ASSERT(it != channels.end());
20 auto channel_state = it->second;
21 gpu.BindChannel(channel_state->bind_id);
22 channel_state->dma_pusher->Push(std::move(entries));
23 channel_state->dma_pusher->DispatchCalls();
24}
25
26void Scheduler::DeclareChannel(std::shared_ptr<ChannelState> new_channel) {
27 s32 channel = new_channel->bind_id;
28 std::unique_lock lk(scheduling_guard);
29 channels.emplace(channel, new_channel);
30}
31
32} // 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..44addf61c
--- /dev/null
+++ b/src/video_core/control/scheduler.h
@@ -0,0 +1,37 @@
1// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include <memory>
7#include <mutex>
8#include <unordered_map>
9
10#include "video_core/dma_pusher.h"
11
12namespace Tegra {
13
14class GPU;
15
16namespace Control {
17
18struct ChannelState;
19
20class Scheduler {
21public:
22 explicit Scheduler(GPU& gpu_);
23 ~Scheduler();
24
25 void Push(s32 channel, CommandList&& entries);
26
27 void DeclareChannel(std::shared_ptr<ChannelState> new_channel);
28
29private:
30 std::unordered_map<s32, std::shared_ptr<ChannelState>> channels;
31 std::mutex scheduling_guard;
32 GPU& gpu;
33};
34
35} // namespace Control
36
37} // namespace Tegra