summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Fernando S2021-10-06 20:02:31 +0200
committerGravatar GitHub2021-10-06 20:02:31 +0200
commitf84328934f5e09894a69d9fa1d2f6a34c715321b (patch)
treeeafe64da6ca2bb195cf5523d3fa13f89f117f897 /src/core
parentMerge pull request #7090 from Moonlacer/tas_spacing_addition (diff)
parentnvflinger: Use jthread and stop_token for VSync thread (diff)
downloadyuzu-f84328934f5e09894a69d9fa1d2f6a34c715321b.tar.gz
yuzu-f84328934f5e09894a69d9fa1d2f6a34c715321b.tar.xz
yuzu-f84328934f5e09894a69d9fa1d2f6a34c715321b.zip
Merge pull request #7118 from ameerj/vc-gpu-impl
gpu: Migrate implementation to the cpp file
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp30
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp13
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp29
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h11
5 files changed, 36 insertions, 52 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index 789000294..4ee8c5733 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -48,8 +48,9 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3
48 addr, offset, width, height, stride, format); 48 addr, offset, width, height, stride, format);
49 49
50 const auto pixel_format = static_cast<Tegra::FramebufferConfig::PixelFormat>(format); 50 const auto pixel_format = static_cast<Tegra::FramebufferConfig::PixelFormat>(format);
51 const Tegra::FramebufferConfig framebuffer{addr, offset, width, height, 51 const auto transform_flags = static_cast<Tegra::FramebufferConfig::TransformFlags>(transform);
52 stride, pixel_format, transform, crop_rect}; 52 const Tegra::FramebufferConfig framebuffer{addr, offset, width, height,
53 stride, pixel_format, transform_flags, crop_rect};
53 54
54 system.GetPerfStats().EndSystemFrame(); 55 system.GetPerfStats().EndSystemFrame();
55 system.GPU().SwapBuffers(&framebuffer); 56 system.GPU().SwapBuffers(&framebuffer);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 775e76330..8b4867ca7 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -111,7 +111,6 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
111 event.event->GetWritableEvent().Signal(); 111 event.event->GetWritableEvent().Signal();
112 return NvResult::Success; 112 return NvResult::Success;
113 } 113 }
114 auto lock = gpu.LockSync();
115 const u32 current_syncpoint_value = event.fence.value; 114 const u32 current_syncpoint_value = event.fence.value;
116 const s32 diff = current_syncpoint_value - params.threshold; 115 const s32 diff = current_syncpoint_value - params.threshold;
117 if (diff >= 0) { 116 if (diff >= 0) {
@@ -132,23 +131,24 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
132 } 131 }
133 132
134 EventState status = events_interface.status[event_id]; 133 EventState status = events_interface.status[event_id];
135 if (event_id < MaxNvEvents || status == EventState::Free || status == EventState::Registered) { 134 const bool bad_parameter = status != EventState::Free && status != EventState::Registered;
136 events_interface.SetEventStatus(event_id, EventState::Waiting); 135 if (bad_parameter) {
137 events_interface.assigned_syncpt[event_id] = params.syncpt_id;
138 events_interface.assigned_value[event_id] = target_value;
139 if (is_async) {
140 params.value = params.syncpt_id << 4;
141 } else {
142 params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
143 }
144 params.value |= event_id;
145 event.event->GetWritableEvent().Clear();
146 gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
147 std::memcpy(output.data(), &params, sizeof(params)); 136 std::memcpy(output.data(), &params, sizeof(params));
148 return NvResult::Timeout; 137 return NvResult::BadParameter;
149 } 138 }
139 events_interface.SetEventStatus(event_id, EventState::Waiting);
140 events_interface.assigned_syncpt[event_id] = params.syncpt_id;
141 events_interface.assigned_value[event_id] = target_value;
142 if (is_async) {
143 params.value = params.syncpt_id << 4;
144 } else {
145 params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
146 }
147 params.value |= event_id;
148 event.event->GetWritableEvent().Clear();
149 gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
150 std::memcpy(output.data(), &params, sizeof(params)); 150 std::memcpy(output.data(), &params, sizeof(params));
151 return NvResult::BadParameter; 151 return NvResult::Timeout;
152} 152}
153 153
154NvResult nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output) { 154NvResult nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output) {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index c0a380088..54ac105d5 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -13,6 +13,14 @@
13#include "video_core/memory_manager.h" 13#include "video_core/memory_manager.h"
14 14
15namespace Service::Nvidia::Devices { 15namespace Service::Nvidia::Devices {
16namespace {
17Tegra::CommandHeader BuildFenceAction(Tegra::GPU::FenceOperation op, u32 syncpoint_id) {
18 Tegra::GPU::FenceAction result{};
19 result.op.Assign(op);
20 result.syncpoint_id.Assign(syncpoint_id);
21 return {result.raw};
22}
23} // namespace
16 24
17nvhost_gpu::nvhost_gpu(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_, 25nvhost_gpu::nvhost_gpu(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
18 SyncpointManager& syncpoint_manager_) 26 SyncpointManager& syncpoint_manager_)
@@ -187,7 +195,7 @@ static std::vector<Tegra::CommandHeader> BuildWaitCommandList(Fence fence) {
187 {fence.value}, 195 {fence.value},
188 Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1, 196 Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
189 Tegra::SubmissionMode::Increasing), 197 Tegra::SubmissionMode::Increasing),
190 Tegra::GPU::FenceAction::Build(Tegra::GPU::FenceOperation::Acquire, fence.id), 198 BuildFenceAction(Tegra::GPU::FenceOperation::Acquire, fence.id),
191 }; 199 };
192} 200}
193 201
@@ -200,8 +208,7 @@ static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(Fence fence,
200 for (u32 count = 0; count < add_increment; ++count) { 208 for (u32 count = 0; count < add_increment; ++count) {
201 result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1, 209 result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
202 Tegra::SubmissionMode::Increasing)); 210 Tegra::SubmissionMode::Increasing));
203 result.emplace_back( 211 result.emplace_back(BuildFenceAction(Tegra::GPU::FenceOperation::Increment, fence.id));
204 Tegra::GPU::FenceAction::Build(Tegra::GPU::FenceOperation::Increment, fence.id));
205 } 212 }
206 213
207 return result; 214 return result;
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 3ead813b0..a22811ec1 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -13,28 +13,20 @@
13#include "common/thread.h" 13#include "common/thread.h"
14#include "core/core.h" 14#include "core/core.h"
15#include "core/core_timing.h" 15#include "core/core_timing.h"
16#include "core/core_timing_util.h"
17#include "core/hardware_properties.h"
18#include "core/hle/kernel/k_readable_event.h" 16#include "core/hle/kernel/k_readable_event.h"
19#include "core/hle/kernel/kernel.h"
20#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" 17#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
21#include "core/hle/service/nvdrv/nvdrv.h" 18#include "core/hle/service/nvdrv/nvdrv.h"
22#include "core/hle/service/nvflinger/buffer_queue.h" 19#include "core/hle/service/nvflinger/buffer_queue.h"
23#include "core/hle/service/nvflinger/nvflinger.h" 20#include "core/hle/service/nvflinger/nvflinger.h"
24#include "core/hle/service/vi/display/vi_display.h" 21#include "core/hle/service/vi/display/vi_display.h"
25#include "core/hle/service/vi/layer/vi_layer.h" 22#include "core/hle/service/vi/layer/vi_layer.h"
26#include "core/perf_stats.h" 23#include "video_core/gpu.h"
27#include "video_core/renderer_base.h"
28 24
29namespace Service::NVFlinger { 25namespace Service::NVFlinger {
30 26
31constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60}; 27constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60};
32 28
33void NVFlinger::VSyncThread(NVFlinger& nv_flinger) { 29void NVFlinger::SplitVSync(std::stop_token stop_token) {
34 nv_flinger.SplitVSync();
35}
36
37void NVFlinger::SplitVSync() {
38 system.RegisterHostThread(); 30 system.RegisterHostThread();
39 std::string name = "yuzu:VSyncThread"; 31 std::string name = "yuzu:VSyncThread";
40 MicroProfileOnThreadCreate(name.c_str()); 32 MicroProfileOnThreadCreate(name.c_str());
@@ -45,7 +37,7 @@ void NVFlinger::SplitVSync() {
45 Common::SetCurrentThreadName(name.c_str()); 37 Common::SetCurrentThreadName(name.c_str());
46 Common::SetCurrentThreadPriority(Common::ThreadPriority::High); 38 Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
47 s64 delay = 0; 39 s64 delay = 0;
48 while (is_running) { 40 while (!stop_token.stop_requested()) {
49 guard->lock(); 41 guard->lock();
50 const s64 time_start = system.CoreTiming().GetGlobalTimeNs().count(); 42 const s64 time_start = system.CoreTiming().GetGlobalTimeNs().count();
51 Compose(); 43 Compose();
@@ -55,7 +47,7 @@ void NVFlinger::SplitVSync() {
55 const s64 next_time = std::max<s64>(0, ticks - time_passed - delay); 47 const s64 next_time = std::max<s64>(0, ticks - time_passed - delay);
56 guard->unlock(); 48 guard->unlock();
57 if (next_time > 0) { 49 if (next_time > 0) {
58 wait_event->WaitFor(std::chrono::nanoseconds{next_time}); 50 std::this_thread::sleep_for(std::chrono::nanoseconds{next_time});
59 } 51 }
60 delay = (system.CoreTiming().GetGlobalTimeNs().count() - time_end) - next_time; 52 delay = (system.CoreTiming().GetGlobalTimeNs().count() - time_end) - next_time;
61 } 53 }
@@ -84,9 +76,7 @@ NVFlinger::NVFlinger(Core::System& system_)
84 }); 76 });
85 77
86 if (system.IsMulticore()) { 78 if (system.IsMulticore()) {
87 is_running = true; 79 vsync_thread = std::jthread([this](std::stop_token token) { SplitVSync(token); });
88 wait_event = std::make_unique<Common::Event>();
89 vsync_thread = std::make_unique<std::thread>(VSyncThread, std::ref(*this));
90 } else { 80 } else {
91 system.CoreTiming().ScheduleEvent(frame_ns, composition_event); 81 system.CoreTiming().ScheduleEvent(frame_ns, composition_event);
92 } 82 }
@@ -96,14 +86,7 @@ NVFlinger::~NVFlinger() {
96 for (auto& buffer_queue : buffer_queues) { 86 for (auto& buffer_queue : buffer_queues) {
97 buffer_queue->Disconnect(); 87 buffer_queue->Disconnect();
98 } 88 }
99 89 if (!system.IsMulticore()) {
100 if (system.IsMulticore()) {
101 is_running = false;
102 wait_event->Set();
103 vsync_thread->join();
104 vsync_thread.reset();
105 wait_event.reset();
106 } else {
107 system.CoreTiming().UnscheduleEvent(composition_event, 0); 90 system.CoreTiming().UnscheduleEvent(composition_event, 0);
108 } 91 }
109} 92}
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 6d84cafb4..7935cf773 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -4,13 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <atomic>
8#include <list> 7#include <list>
9#include <memory> 8#include <memory>
10#include <mutex> 9#include <mutex>
11#include <optional> 10#include <optional>
12#include <string>
13#include <string_view>
14#include <thread> 11#include <thread>
15#include <vector> 12#include <vector>
16 13
@@ -109,9 +106,7 @@ private:
109 /// Creates a layer with the specified layer ID in the desired display. 106 /// Creates a layer with the specified layer ID in the desired display.
110 void CreateLayerAtId(VI::Display& display, u64 layer_id); 107 void CreateLayerAtId(VI::Display& display, u64 layer_id);
111 108
112 static void VSyncThread(NVFlinger& nv_flinger); 109 void SplitVSync(std::stop_token stop_token);
113
114 void SplitVSync();
115 110
116 std::shared_ptr<Nvidia::Module> nvdrv; 111 std::shared_ptr<Nvidia::Module> nvdrv;
117 112
@@ -133,9 +128,7 @@ private:
133 128
134 Core::System& system; 129 Core::System& system;
135 130
136 std::unique_ptr<std::thread> vsync_thread; 131 std::jthread vsync_thread;
137 std::unique_ptr<Common::Event> wait_event;
138 std::atomic<bool> is_running{};
139 132
140 KernelHelpers::ServiceContext service_context; 133 KernelHelpers::ServiceContext service_context;
141}; 134};