summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
authorFernando S <fsahmkow27@gmail.com>2021-10-06 20:02:31 +0200
committerGitHub <noreply@github.com>2021-10-06 20:02:31 +0200
commitf84328934f5e09894a69d9fa1d2f6a34c715321b (patch)
treeeafe64da6ca2bb195cf5523d3fa13f89f117f897 /src/core/hle
parentMerge pull request #7090 from Moonlacer/tas_spacing_addition (diff)
parentnvflinger: Use jthread and stop_token for VSync thread (diff)
downloadyuzu-f84328934f5e09894a69d9fa1d2f6a34c715321b.tar
yuzu-f84328934f5e09894a69d9fa1d2f6a34c715321b.tar.gz
yuzu-f84328934f5e09894a69d9fa1d2f6a34c715321b.tar.bz2
yuzu-f84328934f5e09894a69d9fa1d2f6a34c715321b.tar.lz
yuzu-f84328934f5e09894a69d9fa1d2f6a34c715321b.tar.xz
yuzu-f84328934f5e09894a69d9fa1d2f6a34c715321b.tar.zst
yuzu-f84328934f5e09894a69d9fa1d2f6a34c715321b.zip
Diffstat (limited to 'src/core/hle')
-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
addr, offset, width, height, stride, format);
const auto pixel_format = static_cast<Tegra::FramebufferConfig::PixelFormat>(format);
- const Tegra::FramebufferConfig framebuffer{addr, offset, width, height,
- stride, pixel_format, transform, crop_rect};
+ const auto transform_flags = static_cast<Tegra::FramebufferConfig::TransformFlags>(transform);
+ const Tegra::FramebufferConfig framebuffer{addr, offset, width, height,
+ stride, pixel_format, transform_flags, crop_rect};
system.GetPerfStats().EndSystemFrame();
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
event.event->GetWritableEvent().Signal();
return NvResult::Success;
}
- auto lock = gpu.LockSync();
const u32 current_syncpoint_value = event.fence.value;
const s32 diff = current_syncpoint_value - params.threshold;
if (diff >= 0) {
@@ -132,23 +131,24 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
}
EventState status = events_interface.status[event_id];
- if (event_id < MaxNvEvents || status == EventState::Free || status == EventState::Registered) {
- events_interface.SetEventStatus(event_id, EventState::Waiting);
- events_interface.assigned_syncpt[event_id] = params.syncpt_id;
- events_interface.assigned_value[event_id] = target_value;
- if (is_async) {
- params.value = params.syncpt_id << 4;
- } else {
- params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
- }
- params.value |= event_id;
- event.event->GetWritableEvent().Clear();
- gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
+ const bool bad_parameter = status != EventState::Free && status != EventState::Registered;
+ if (bad_parameter) {
std::memcpy(output.data(), &params, sizeof(params));
- return NvResult::Timeout;
+ return NvResult::BadParameter;
}
+ events_interface.SetEventStatus(event_id, EventState::Waiting);
+ events_interface.assigned_syncpt[event_id] = params.syncpt_id;
+ events_interface.assigned_value[event_id] = target_value;
+ if (is_async) {
+ params.value = params.syncpt_id << 4;
+ } else {
+ params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
+ }
+ params.value |= event_id;
+ event.event->GetWritableEvent().Clear();
+ gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
std::memcpy(output.data(), &params, sizeof(params));
- return NvResult::BadParameter;
+ return NvResult::Timeout;
}
NvResult 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 @@
#include "video_core/memory_manager.h"
namespace Service::Nvidia::Devices {
+namespace {
+Tegra::CommandHeader BuildFenceAction(Tegra::GPU::FenceOperation op, u32 syncpoint_id) {
+ Tegra::GPU::FenceAction result{};
+ result.op.Assign(op);
+ result.syncpoint_id.Assign(syncpoint_id);
+ return {result.raw};
+}
+} // namespace
nvhost_gpu::nvhost_gpu(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
SyncpointManager& syncpoint_manager_)
@@ -187,7 +195,7 @@ static std::vector<Tegra::CommandHeader> BuildWaitCommandList(Fence fence) {
{fence.value},
Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
Tegra::SubmissionMode::Increasing),
- Tegra::GPU::FenceAction::Build(Tegra::GPU::FenceOperation::Acquire, fence.id),
+ BuildFenceAction(Tegra::GPU::FenceOperation::Acquire, fence.id),
};
}
@@ -200,8 +208,7 @@ static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(Fence fence,
for (u32 count = 0; count < add_increment; ++count) {
result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
Tegra::SubmissionMode::Increasing));
- result.emplace_back(
- Tegra::GPU::FenceAction::Build(Tegra::GPU::FenceOperation::Increment, fence.id));
+ result.emplace_back(BuildFenceAction(Tegra::GPU::FenceOperation::Increment, fence.id));
}
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 @@
#include "common/thread.h"
#include "core/core.h"
#include "core/core_timing.h"
-#include "core/core_timing_util.h"
-#include "core/hardware_properties.h"
#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/kernel/kernel.h"
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/nvflinger/buffer_queue.h"
#include "core/hle/service/nvflinger/nvflinger.h"
#include "core/hle/service/vi/display/vi_display.h"
#include "core/hle/service/vi/layer/vi_layer.h"
-#include "core/perf_stats.h"
-#include "video_core/renderer_base.h"
+#include "video_core/gpu.h"
namespace Service::NVFlinger {
constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60};
-void NVFlinger::VSyncThread(NVFlinger& nv_flinger) {
- nv_flinger.SplitVSync();
-}
-
-void NVFlinger::SplitVSync() {
+void NVFlinger::SplitVSync(std::stop_token stop_token) {
system.RegisterHostThread();
std::string name = "yuzu:VSyncThread";
MicroProfileOnThreadCreate(name.c_str());
@@ -45,7 +37,7 @@ void NVFlinger::SplitVSync() {
Common::SetCurrentThreadName(name.c_str());
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
s64 delay = 0;
- while (is_running) {
+ while (!stop_token.stop_requested()) {
guard->lock();
const s64 time_start = system.CoreTiming().GetGlobalTimeNs().count();
Compose();
@@ -55,7 +47,7 @@ void NVFlinger::SplitVSync() {
const s64 next_time = std::max<s64>(0, ticks - time_passed - delay);
guard->unlock();
if (next_time > 0) {
- wait_event->WaitFor(std::chrono::nanoseconds{next_time});
+ std::this_thread::sleep_for(std::chrono::nanoseconds{next_time});
}
delay = (system.CoreTiming().GetGlobalTimeNs().count() - time_end) - next_time;
}
@@ -84,9 +76,7 @@ NVFlinger::NVFlinger(Core::System& system_)
});
if (system.IsMulticore()) {
- is_running = true;
- wait_event = std::make_unique<Common::Event>();
- vsync_thread = std::make_unique<std::thread>(VSyncThread, std::ref(*this));
+ vsync_thread = std::jthread([this](std::stop_token token) { SplitVSync(token); });
} else {
system.CoreTiming().ScheduleEvent(frame_ns, composition_event);
}
@@ -96,14 +86,7 @@ NVFlinger::~NVFlinger() {
for (auto& buffer_queue : buffer_queues) {
buffer_queue->Disconnect();
}
-
- if (system.IsMulticore()) {
- is_running = false;
- wait_event->Set();
- vsync_thread->join();
- vsync_thread.reset();
- wait_event.reset();
- } else {
+ if (!system.IsMulticore()) {
system.CoreTiming().UnscheduleEvent(composition_event, 0);
}
}
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 @@
#pragma once
-#include <atomic>
#include <list>
#include <memory>
#include <mutex>
#include <optional>
-#include <string>
-#include <string_view>
#include <thread>
#include <vector>
@@ -109,9 +106,7 @@ private:
/// Creates a layer with the specified layer ID in the desired display.
void CreateLayerAtId(VI::Display& display, u64 layer_id);
- static void VSyncThread(NVFlinger& nv_flinger);
-
- void SplitVSync();
+ void SplitVSync(std::stop_token stop_token);
std::shared_ptr<Nvidia::Module> nvdrv;
@@ -133,9 +128,7 @@ private:
Core::System& system;
- std::unique_ptr<std::thread> vsync_thread;
- std::unique_ptr<Common::Event> wait_event;
- std::atomic<bool> is_running{};
+ std::jthread vsync_thread;
KernelHelpers::ServiceContext service_context;
};