summaryrefslogtreecommitdiff
path: root/src/video_core/control
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-11-05 15:52:31 +0100
committerGravatar Fernando Sahmkow2022-10-06 21:00:51 +0200
commit139ea93512aeead8a4aee3910a3de86eb109a838 (patch)
tree857643fc08617b7035656a51728c399f30c8c2cb /src/video_core/control
parentNVASGPU: Fix Remap. (diff)
downloadyuzu-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.cpp44
-rw-r--r--src/video_core/control/channel_state.h69
-rw-r--r--src/video_core/control/channel_state_cache.cpp5
-rw-r--r--src/video_core/control/channel_state_cache.h68
-rw-r--r--src/video_core/control/channel_state_cache.inc64
-rw-r--r--src/video_core/control/scheduler.cpp31
-rw-r--r--src/video_core/control/scheduler.h38
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
16namespace Tegra::Control {
17
18ChannelState::ChannelState(s32 bind_id_) {
19 bind_id = bind_id_;
20 initiated = false;
21}
22
23void 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
34void 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
11namespace Core {
12class System;
13}
14
15namespace VideoCore {
16class RasterizerInterface;
17}
18
19namespace Tegra {
20
21class GPU;
22
23namespace Engines {
24class Puller;
25class Fermi2D;
26class Maxwell3D;
27class MaxwellDMA;
28class KeplerCompute;
29class KeplerMemory;
30} // namespace Engines
31
32class MemoryManager;
33class DmaPusher;
34
35namespace Control {
36
37struct 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
3namespace VideoCommon {
4template 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
9namespace Tegra {
10
11namespace Engines {
12class Maxwell3D;
13class KeplerCompute;
14} // namespace Engines
15
16class MemoryManager;
17
18namespace Control {
19struct ChannelState;
20}
21
22} // namespace Tegra
23
24namespace VideoCommon {
25
26class ChannelInfo {
27public:
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
40template <class P>
41class ChannelSetupCaches {
42public:
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
54protected:
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
7namespace VideoCommon {
8
9ChannelInfo::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
13template <class P>
14void 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.
33template <class P>
34void 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.
45template <class P>
46void 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
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<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
25void 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
13namespace Tegra {
14
15class GPU;
16
17namespace Control {
18
19struct ChannelState;
20
21class Scheduler {
22public:
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
30private:
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