summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2022-01-30 10:31:13 +0100
committerGravatar Fernando Sahmkow2022-10-06 21:00:52 +0200
commit668e80a9f42fb4ce0e16f6381d05bcbd286b2da1 (patch)
treea1c668d6c3d00eade849b1d31dba4116095e4c12 /src/core
parentTexture Cache: Fix GC and GPU Modified on Joins. (diff)
downloadyuzu-668e80a9f42fb4ce0e16f6381d05bcbd286b2da1.tar.gz
yuzu-668e80a9f42fb4ce0e16f6381d05bcbd286b2da1.tar.xz
yuzu-668e80a9f42fb4ce0e16f6381d05bcbd286b2da1.zip
VideoCore: Refactor syncing.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/core.cpp12
-rw-r--r--src/core/core.h9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp19
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h4
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp10
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp9
7 files changed, 53 insertions, 12 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 121092868..fa059a394 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -51,6 +51,7 @@
51#include "core/telemetry_session.h" 51#include "core/telemetry_session.h"
52#include "core/tools/freezer.h" 52#include "core/tools/freezer.h"
53#include "network/network.h" 53#include "network/network.h"
54#include "video_core/host1x/host1x.h"
54#include "video_core/renderer_base.h" 55#include "video_core/renderer_base.h"
55#include "video_core/video_core.h" 56#include "video_core/video_core.h"
56 57
@@ -215,6 +216,7 @@ struct System::Impl {
215 216
216 telemetry_session = std::make_unique<Core::TelemetrySession>(); 217 telemetry_session = std::make_unique<Core::TelemetrySession>();
217 218
219 host1x_core = std::make_unique<Tegra::Host1x::Host1x>();
218 gpu_core = VideoCore::CreateGPU(emu_window, system); 220 gpu_core = VideoCore::CreateGPU(emu_window, system);
219 if (!gpu_core) { 221 if (!gpu_core) {
220 return SystemResultStatus::ErrorVideoCore; 222 return SystemResultStatus::ErrorVideoCore;
@@ -373,6 +375,7 @@ struct System::Impl {
373 app_loader.reset(); 375 app_loader.reset();
374 audio_core.reset(); 376 audio_core.reset();
375 gpu_core.reset(); 377 gpu_core.reset();
378 host1x_core.reset();
376 perf_stats.reset(); 379 perf_stats.reset();
377 kernel.Shutdown(); 380 kernel.Shutdown();
378 memory.Reset(); 381 memory.Reset();
@@ -450,6 +453,7 @@ struct System::Impl {
450 /// AppLoader used to load the current executing application 453 /// AppLoader used to load the current executing application
451 std::unique_ptr<Loader::AppLoader> app_loader; 454 std::unique_ptr<Loader::AppLoader> app_loader;
452 std::unique_ptr<Tegra::GPU> gpu_core; 455 std::unique_ptr<Tegra::GPU> gpu_core;
456 std::unique_ptr<Tegra::Host1x::Host1x> host1x_core;
453 std::unique_ptr<Hardware::InterruptManager> interrupt_manager; 457 std::unique_ptr<Hardware::InterruptManager> interrupt_manager;
454 std::unique_ptr<Core::DeviceMemory> device_memory; 458 std::unique_ptr<Core::DeviceMemory> device_memory;
455 std::unique_ptr<AudioCore::AudioCore> audio_core; 459 std::unique_ptr<AudioCore::AudioCore> audio_core;
@@ -668,6 +672,14 @@ const Tegra::GPU& System::GPU() const {
668 return *impl->gpu_core; 672 return *impl->gpu_core;
669} 673}
670 674
675Tegra::Host1x::Host1x& System::Host1x() {
676 return *impl->host1x_core;
677}
678
679const Tegra::Host1x::Host1x& System::Host1x() const {
680 return *impl->host1x_core;
681}
682
671Core::Hardware::InterruptManager& System::InterruptManager() { 683Core::Hardware::InterruptManager& System::InterruptManager() {
672 return *impl->interrupt_manager; 684 return *impl->interrupt_manager;
673} 685}
diff --git a/src/core/core.h b/src/core/core.h
index 0ce3b1d60..e4168a921 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -74,6 +74,9 @@ class TimeManager;
74namespace Tegra { 74namespace Tegra {
75class DebugContext; 75class DebugContext;
76class GPU; 76class GPU;
77namespace Host1x {
78class Host1x;
79} // namespace Host1x
77} // namespace Tegra 80} // namespace Tegra
78 81
79namespace VideoCore { 82namespace VideoCore {
@@ -260,6 +263,12 @@ public:
260 /// Gets an immutable reference to the GPU interface. 263 /// Gets an immutable reference to the GPU interface.
261 [[nodiscard]] const Tegra::GPU& GPU() const; 264 [[nodiscard]] const Tegra::GPU& GPU() const;
262 265
266 /// Gets a mutable reference to the Host1x interface
267 [[nodiscard]] Tegra::Host1x::Host1x& Host1x();
268
269 /// Gets an immutable reference to the Host1x interface.
270 [[nodiscard]] const Tegra::Host1x::Host1x& Host1x() const;
271
263 /// Gets a mutable reference to the renderer. 272 /// Gets a mutable reference to the renderer.
264 [[nodiscard]] VideoCore::RendererBase& Renderer(); 273 [[nodiscard]] VideoCore::RendererBase& Renderer();
265 274
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index b1c0e9eb2..e6a976714 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -50,7 +50,7 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, android::PixelFormat form
50 stride, format, transform, crop_rect}; 50 stride, format, transform, crop_rect};
51 51
52 system.GetPerfStats().EndSystemFrame(); 52 system.GetPerfStats().EndSystemFrame();
53 system.GPU().SwapBuffers(&framebuffer); 53 system.GPU().RequestSwapBuffers(&framebuffer, nullptr, 0);
54 system.SpeedLimiter().DoSpeedLimiting(system.CoreTiming().GetGlobalTimeUs()); 54 system.SpeedLimiter().DoSpeedLimiting(system.CoreTiming().GetGlobalTimeUs());
55 system.GetPerfStats().BeginSystemFrame(); 55 system.GetPerfStats().BeginSystemFrame();
56} 56}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 54074af75..ffe42d423 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -18,6 +18,7 @@
18#include "core/hle/service/nvdrv/core/syncpoint_manager.h" 18#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
19#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" 19#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h"
20#include "video_core/gpu.h" 20#include "video_core/gpu.h"
21#include "video_core/host1x/host1x.h"
21 22
22namespace Service::Nvidia::Devices { 23namespace Service::Nvidia::Devices {
23 24
@@ -129,7 +130,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
129 return NvResult::Success; 130 return NvResult::Success;
130 } 131 }
131 132
132 auto& gpu = system.GPU(); 133 auto& host1x_syncpoint_manager = system.Host1x().GetSyncpointManager();
133 const u32 target_value = params.fence.value; 134 const u32 target_value = params.fence.value;
134 135
135 auto lock = NvEventsLock(); 136 auto lock = NvEventsLock();
@@ -149,7 +150,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
149 if (events[slot].fails > 2) { 150 if (events[slot].fails > 2) {
150 { 151 {
151 auto lk = system.StallProcesses(); 152 auto lk = system.StallProcesses();
152 gpu.WaitFence(fence_id, target_value); 153 host1x_syncpoint_manager.WaitHost(fence_id, target_value);
153 system.UnstallProcesses(); 154 system.UnstallProcesses();
154 } 155 }
155 params.value.raw = target_value; 156 params.value.raw = target_value;
@@ -198,7 +199,15 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
198 } 199 }
199 params.value.raw |= slot; 200 params.value.raw |= slot;
200 201
201 gpu.RegisterSyncptInterrupt(fence_id, target_value); 202 event.wait_handle =
203 host1x_syncpoint_manager.RegisterHostAction(fence_id, target_value, [this, slot]() {
204 auto& event = events[slot];
205 if (event.status.exchange(EventState::Signalling, std::memory_order_acq_rel) ==
206 EventState::Waiting) {
207 event.kevent->GetWritableEvent().Signal();
208 }
209 event.status.store(EventState::Signalled, std::memory_order_release);
210 });
202 return NvResult::Timeout; 211 return NvResult::Timeout;
203} 212}
204 213
@@ -288,8 +297,10 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::v
288 auto& event = events[event_id]; 297 auto& event = events[event_id];
289 if (event.status.exchange(EventState::Cancelling, std::memory_order_acq_rel) == 298 if (event.status.exchange(EventState::Cancelling, std::memory_order_acq_rel) ==
290 EventState::Waiting) { 299 EventState::Waiting) {
291 system.GPU().CancelSyncptInterrupt(event.assigned_syncpt, event.assigned_value); 300 auto& host1x_syncpoint_manager = system.Host1x().GetSyncpointManager();
301 host1x_syncpoint_manager.DeregisterHostAction(event.assigned_syncpt, event.wait_handle);
292 syncpoint_manager.RefreshSyncpoint(event.assigned_syncpt); 302 syncpoint_manager.RefreshSyncpoint(event.assigned_syncpt);
303 event.wait_handle = {};
293 } 304 }
294 event.fails++; 305 event.fails++;
295 event.status.store(EventState::Cancelled, std::memory_order_release); 306 event.status.store(EventState::Cancelled, std::memory_order_release);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index d56aea405..136a1e925 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -11,6 +11,7 @@
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/hle/service/nvdrv/devices/nvdevice.h" 12#include "core/hle/service/nvdrv/devices/nvdevice.h"
13#include "core/hle/service/nvdrv/nvdrv.h" 13#include "core/hle/service/nvdrv/nvdrv.h"
14#include "video_core/host1x/syncpoint_manager.h"
14 15
15namespace Service::Nvidia::NvCore { 16namespace Service::Nvidia::NvCore {
16class Container; 17class Container;
@@ -78,6 +79,9 @@ private:
78 // Tells if an NVEvent is registered or not 79 // Tells if an NVEvent is registered or not
79 bool registered{}; 80 bool registered{};
80 81
82 // Used for waiting on a syncpoint & canceling it.
83 Tegra::Host1x::SyncpointManager::ActionHandle wait_handle{};
84
81 bool IsBeingUsed() { 85 bool IsBeingUsed() {
82 const auto current_status = status.load(std::memory_order_acquire); 86 const auto current_status = status.load(std::memory_order_acquire);
83 return current_status == EventState::Waiting || 87 return current_status == EventState::Waiting ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 38d45cb79..db3e266ad 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -210,10 +210,10 @@ NvResult nvhost_gpu::AllocateObjectContext(const std::vector<u8>& input, std::ve
210 210
211static std::vector<Tegra::CommandHeader> BuildWaitCommandList(NvFence fence) { 211static std::vector<Tegra::CommandHeader> BuildWaitCommandList(NvFence fence) {
212 return { 212 return {
213 Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceValue, 1, 213 Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1,
214 Tegra::SubmissionMode::Increasing), 214 Tegra::SubmissionMode::Increasing),
215 {fence.value}, 215 {fence.value},
216 Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1, 216 Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointOperation, 1,
217 Tegra::SubmissionMode::Increasing), 217 Tegra::SubmissionMode::Increasing),
218 BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Acquire, fence.id), 218 BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Acquire, fence.id),
219 }; 219 };
@@ -222,12 +222,12 @@ static std::vector<Tegra::CommandHeader> BuildWaitCommandList(NvFence fence) {
222static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(NvFence fence, 222static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(NvFence fence,
223 u32 add_increment) { 223 u32 add_increment) {
224 std::vector<Tegra::CommandHeader> result{ 224 std::vector<Tegra::CommandHeader> result{
225 Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceValue, 1, 225 Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1,
226 Tegra::SubmissionMode::Increasing), 226 Tegra::SubmissionMode::Increasing),
227 {}}; 227 {}};
228 228
229 for (u32 count = 0; count < add_increment; ++count) { 229 for (u32 count = 0; count < add_increment; ++count) {
230 result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1, 230 result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointOperation, 1,
231 Tegra::SubmissionMode::Increasing)); 231 Tegra::SubmissionMode::Increasing));
232 result.emplace_back( 232 result.emplace_back(
233 BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Increment, fence.id)); 233 BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Increment, fence.id));
@@ -239,7 +239,7 @@ static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(NvFence fence
239static std::vector<Tegra::CommandHeader> BuildIncrementWithWfiCommandList(NvFence fence, 239static std::vector<Tegra::CommandHeader> BuildIncrementWithWfiCommandList(NvFence fence,
240 u32 add_increment) { 240 u32 add_increment) {
241 std::vector<Tegra::CommandHeader> result{ 241 std::vector<Tegra::CommandHeader> result{
242 Tegra::BuildCommandHeader(Tegra::BufferMethods::WaitForInterrupt, 1, 242 Tegra::BuildCommandHeader(Tegra::BufferMethods::WaitForIdle, 1,
243 Tegra::SubmissionMode::Increasing), 243 Tegra::SubmissionMode::Increasing),
244 {}}; 244 {}};
245 const std::vector<Tegra::CommandHeader> increment{ 245 const std::vector<Tegra::CommandHeader> increment{
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 8c3013f83..aa112021d 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -24,6 +24,8 @@
24#include "core/hle/service/vi/layer/vi_layer.h" 24#include "core/hle/service/vi/layer/vi_layer.h"
25#include "core/hle/service/vi/vi_results.h" 25#include "core/hle/service/vi/vi_results.h"
26#include "video_core/gpu.h" 26#include "video_core/gpu.h"
27#include "video_core/host1x/host1x.h"
28#include "video_core/host1x/syncpoint_manager.h"
27 29
28namespace Service::NVFlinger { 30namespace Service::NVFlinger {
29 31
@@ -267,12 +269,12 @@ void NVFlinger::Compose() {
267 return; // We are likely shutting down 269 return; // We are likely shutting down
268 } 270 }
269 271
270 auto& gpu = system.GPU(); 272 auto& syncpoint_manager = system.Host1x().GetSyncpointManager();
271 const auto& multi_fence = buffer.fence; 273 const auto& multi_fence = buffer.fence;
272 guard->unlock(); 274 guard->unlock();
273 for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) { 275 for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) {
274 const auto& fence = multi_fence.fences[fence_id]; 276 const auto& fence = multi_fence.fences[fence_id];
275 gpu.WaitFence(fence.id, fence.value); 277 syncpoint_manager.WaitGuest(fence.id, fence.value);
276 } 278 }
277 guard->lock(); 279 guard->lock();
278 280
@@ -284,6 +286,7 @@ void NVFlinger::Compose() {
284 auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>(disp_fd); 286 auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>(disp_fd);
285 ASSERT(nvdisp); 287 ASSERT(nvdisp);
286 288
289 guard->unlock();
287 Common::Rectangle<int> crop_rect{ 290 Common::Rectangle<int> crop_rect{
288 static_cast<int>(buffer.crop.Left()), static_cast<int>(buffer.crop.Top()), 291 static_cast<int>(buffer.crop.Left()), static_cast<int>(buffer.crop.Top()),
289 static_cast<int>(buffer.crop.Right()), static_cast<int>(buffer.crop.Bottom())}; 292 static_cast<int>(buffer.crop.Right()), static_cast<int>(buffer.crop.Bottom())};
@@ -292,6 +295,8 @@ void NVFlinger::Compose() {
292 igbp_buffer.Width(), igbp_buffer.Height(), igbp_buffer.Stride(), 295 igbp_buffer.Width(), igbp_buffer.Height(), igbp_buffer.Stride(),
293 static_cast<android::BufferTransformFlags>(buffer.transform), crop_rect); 296 static_cast<android::BufferTransformFlags>(buffer.transform), crop_rect);
294 297
298 guard->lock();
299
295 swap_interval = buffer.swap_interval; 300 swap_interval = buffer.swap_interval;
296 301
297 auto fence = android::Fence::NoFence(); 302 auto fence = android::Fence::NoFence();