From 427bf76e621cf0833bc1bbec7d8be891297223e7 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Fri, 1 Oct 2021 00:57:02 -0400 Subject: gpu: Migrate implementation to the cpp file --- src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 5 +++-- src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | 13 ++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src/core') 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(format); - const Tegra::FramebufferConfig framebuffer{addr, offset, width, height, - stride, pixel_format, transform, crop_rect}; + const auto transform_flags = static_cast(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_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_dev_, SyncpointManager& syncpoint_manager_) @@ -187,7 +195,7 @@ static std::vector 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 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; -- cgit v1.2.3 From 6c0d90237371c9adbe80a26c3e4f53b35ea57a0e Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Fri, 1 Oct 2021 23:10:55 -0400 Subject: nvhost_ctrl: Refactor usage of gpu.LockSync() This seems to only be used to protect a later gpu function call. So we can move the lock into that call instead. --- src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'src/core') 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& 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& 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(), ¶ms, 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(), ¶ms, sizeof(params)); - return NvResult::BadParameter; + return NvResult::Timeout; } NvResult nvhost_ctrl::IocCtrlEventRegister(const std::vector& input, std::vector& output) { -- cgit v1.2.3 From 71e19153ef9309dbcdd9ada95068917f0d0dd44c Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 2 Oct 2021 00:39:57 -0400 Subject: nvflinger: Use jthread and stop_token for VSync thread Avoids a destruction data race that may occur on the vsync thread --- src/core/hle/service/nvflinger/nvflinger.cpp | 29 ++++++---------------------- src/core/hle/service/nvflinger/nvflinger.h | 11 ++--------- 2 files changed, 8 insertions(+), 32 deletions(-) (limited to 'src/core') 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(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(); - vsync_thread = std::make_unique(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 #include #include #include #include -#include -#include #include #include @@ -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 nvdrv; @@ -133,9 +128,7 @@ private: Core::System& system; - std::unique_ptr vsync_thread; - std::unique_ptr wait_event; - std::atomic is_running{}; + std::jthread vsync_thread; KernelHelpers::ServiceContext service_context; }; -- cgit v1.2.3