3
0
Fork 0
forked from suyu/suyu

NVServices: Styling, define constructors as explicit and corrections

This commit is contained in:
Fernando Sahmkow 2019-06-18 20:53:21 -04:00 committed by FernandoS27
parent b391e5f638
commit d20ede40b1
24 changed files with 73 additions and 65 deletions

View file

@ -1,5 +1,9 @@
// Copyright 2019 Yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h"
#include "core/hardware_interrupt_manager.h" #include "core/hardware_interrupt_manager.h"
#include "core/hle/service/nvdrv/interface.h" #include "core/hle/service/nvdrv/interface.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
@ -11,11 +15,13 @@ InterruptManager::InterruptManager(Core::System& system_in) : system(system_in)
system.CoreTiming().RegisterEvent("GPUInterrupt", [this](u64 message, s64) { system.CoreTiming().RegisterEvent("GPUInterrupt", [this](u64 message, s64) {
auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv"); auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv");
const u32 syncpt = static_cast<u32>(message >> 32); const u32 syncpt = static_cast<u32>(message >> 32);
const u32 value = static_cast<u32>(message & 0x00000000FFFFFFFFULL); const u32 value = static_cast<u32>(message);
nvdrv->SignalGPUInterruptSyncpt(syncpt, value); nvdrv->SignalGPUInterruptSyncpt(syncpt, value);
}); });
} }
InterruptManager::~InterruptManager() = default;
void InterruptManager::GPUInterruptSyncpt(const u32 syncpoint_id, const u32 value) { void InterruptManager::GPUInterruptSyncpt(const u32 syncpoint_id, const u32 value) {
const u64 msg = (static_cast<u64>(syncpoint_id) << 32ULL) | value; const u64 msg = (static_cast<u64>(syncpoint_id) << 32ULL) | value;
system.CoreTiming().ScheduleEvent(10, gpu_interrupt_event, msg); system.CoreTiming().ScheduleEvent(10, gpu_interrupt_event, msg);

View file

@ -1,20 +1,27 @@
// Copyright 2019 Yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once #pragma once
#include "common/common_types.h" #include "common/common_types.h"
#include "core/core_timing.h"
namespace Core { namespace Core {
class System; class System;
} }
namespace Core::Timing {
struct EventType;
}
namespace Core::Hardware { namespace Core::Hardware {
class InterruptManager { class InterruptManager {
public: public:
InterruptManager(Core::System& system); explicit InterruptManager(Core::System& system);
~InterruptManager() = default; ~InterruptManager();
void GPUInterruptSyncpt(const u32 syncpoint_id, const u32 value); void GPUInterruptSyncpt(u32 syncpoint_id, u32 value);
private: private:
Core::System& system; Core::System& system;

View file

@ -20,7 +20,7 @@ namespace Service::Nvidia::Devices {
/// implement the ioctl interface. /// implement the ioctl interface.
class nvdevice { class nvdevice {
public: public:
nvdevice(Core::System& system) : system{system} {}; explicit nvdevice(Core::System& system) : system{system} {};
virtual ~nvdevice() = default; virtual ~nvdevice() = default;
union Ioctl { union Ioctl {
u32_le raw; u32_le raw;

View file

@ -15,7 +15,7 @@
namespace Service::Nvidia::Devices { namespace Service::Nvidia::Devices {
nvhost_ctrl::nvhost_ctrl(Core::System& system, EventsInterface& events_interface) nvhost_ctrl::nvhost_ctrl(Core::System& system, EventInterface& events_interface)
: nvdevice(system), events_interface{events_interface} {} : nvdevice(system), events_interface{events_interface} {}
nvhost_ctrl::~nvhost_ctrl() = default; nvhost_ctrl::~nvhost_ctrl() = default;
@ -67,12 +67,11 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
if (!gpu.IsAsync()) { if (!gpu.IsAsync()) {
return NvResult::Success; return NvResult::Success;
} }
gpu.Guard(true); auto lock = gpu.LockSync();
u32 current_syncpoint_value = gpu.GetSyncpointValue(params.syncpt_id); u32 current_syncpoint_value = gpu.GetSyncpointValue(params.syncpt_id);
if (current_syncpoint_value >= params.threshold) { if (current_syncpoint_value >= params.threshold) {
params.value = current_syncpoint_value; params.value = current_syncpoint_value;
std::memcpy(output.data(), &params, sizeof(params)); std::memcpy(output.data(), &params, sizeof(params));
gpu.Guard(false);
return NvResult::Success; return NvResult::Success;
} }
@ -82,7 +81,6 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
if (params.timeout == 0) { if (params.timeout == 0) {
std::memcpy(output.data(), &params, sizeof(params)); std::memcpy(output.data(), &params, sizeof(params));
gpu.Guard(false);
return NvResult::Timeout; return NvResult::Timeout;
} }
@ -91,7 +89,6 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
event_id = params.value & 0x00FF; event_id = params.value & 0x00FF;
if (event_id >= 64) { if (event_id >= 64) {
std::memcpy(output.data(), &params, sizeof(params)); std::memcpy(output.data(), &params, sizeof(params));
gpu.Guard(false);
return NvResult::BadParameter; return NvResult::BadParameter;
} }
} else { } else {
@ -119,15 +116,12 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
ctrl.must_delay = true; ctrl.must_delay = true;
ctrl.timeout = params.timeout; ctrl.timeout = params.timeout;
ctrl.event_id = event_id; ctrl.event_id = event_id;
gpu.Guard(false);
return NvResult::Timeout; return NvResult::Timeout;
} }
std::memcpy(output.data(), &params, sizeof(params)); std::memcpy(output.data(), &params, sizeof(params));
gpu.Guard(false);
return NvResult::Timeout; return NvResult::Timeout;
} }
std::memcpy(output.data(), &params, sizeof(params)); std::memcpy(output.data(), &params, sizeof(params));
gpu.Guard(false);
return NvResult::BadParameter; return NvResult::BadParameter;
} }

View file

@ -14,7 +14,7 @@ namespace Service::Nvidia::Devices {
class nvhost_ctrl final : public nvdevice { class nvhost_ctrl final : public nvdevice {
public: public:
nvhost_ctrl(Core::System& system, EventsInterface& events_interface); explicit nvhost_ctrl(Core::System& system, EventInterface& events_interface);
~nvhost_ctrl() override; ~nvhost_ctrl() override;
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
@ -143,7 +143,7 @@ private:
u32 IocCtrlEventSignal(const std::vector<u8>& input, std::vector<u8>& output); u32 IocCtrlEventSignal(const std::vector<u8>& input, std::vector<u8>& output);
EventsInterface& events_interface; EventInterface& events_interface;
}; };
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices

View file

@ -12,7 +12,7 @@
namespace Service::Nvidia::Devices { namespace Service::Nvidia::Devices {
nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system){}; nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system) {}
nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default; nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default;
u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,

View file

@ -13,7 +13,7 @@ namespace Service::Nvidia::Devices {
class nvhost_ctrl_gpu final : public nvdevice { class nvhost_ctrl_gpu final : public nvdevice {
public: public:
nvhost_ctrl_gpu(Core::System& system); explicit nvhost_ctrl_gpu(Core::System& system);
~nvhost_ctrl_gpu() override; ~nvhost_ctrl_gpu() override;
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,

View file

@ -10,7 +10,7 @@
namespace Service::Nvidia::Devices { namespace Service::Nvidia::Devices {
nvhost_nvdec::nvhost_nvdec(Core::System& system) : nvdevice(system){}; nvhost_nvdec::nvhost_nvdec(Core::System& system) : nvdevice(system) {}
nvhost_nvdec::~nvhost_nvdec() = default; nvhost_nvdec::~nvhost_nvdec() = default;
u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,

View file

@ -13,7 +13,7 @@ namespace Service::Nvidia::Devices {
class nvhost_nvdec final : public nvdevice { class nvhost_nvdec final : public nvdevice {
public: public:
nvhost_nvdec(Core::System& system); explicit nvhost_nvdec(Core::System& system);
~nvhost_nvdec() override; ~nvhost_nvdec() override;
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,

View file

@ -10,7 +10,7 @@
namespace Service::Nvidia::Devices { namespace Service::Nvidia::Devices {
nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system){}; nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {}
nvhost_nvjpg::~nvhost_nvjpg() = default; nvhost_nvjpg::~nvhost_nvjpg() = default;
u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,

View file

@ -13,7 +13,7 @@ namespace Service::Nvidia::Devices {
class nvhost_nvjpg final : public nvdevice { class nvhost_nvjpg final : public nvdevice {
public: public:
nvhost_nvjpg(Core::System& system); explicit nvhost_nvjpg(Core::System& system);
~nvhost_nvjpg() override; ~nvhost_nvjpg() override;
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,

View file

@ -10,7 +10,7 @@
namespace Service::Nvidia::Devices { namespace Service::Nvidia::Devices {
nvhost_vic::nvhost_vic(Core::System& system) : nvdevice(system){}; nvhost_vic::nvhost_vic(Core::System& system) : nvdevice(system) {}
nvhost_vic::~nvhost_vic() = default; nvhost_vic::~nvhost_vic() = default;
u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,

View file

@ -13,7 +13,7 @@ namespace Service::Nvidia::Devices {
class nvhost_vic final : public nvdevice { class nvhost_vic final : public nvdevice {
public: public:
nvhost_vic(Core::System& system); explicit nvhost_vic(Core::System& system);
~nvhost_vic() override; ~nvhost_vic() override;
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,

View file

@ -18,7 +18,7 @@ enum {
}; };
} }
nvmap::nvmap(Core::System& system) : nvdevice(system){}; nvmap::nvmap(Core::System& system) : nvdevice(system) {}
nvmap::~nvmap() = default; nvmap::~nvmap() = default;
VAddr nvmap::GetObjectAddress(u32 handle) const { VAddr nvmap::GetObjectAddress(u32 handle) const {

View file

@ -16,7 +16,7 @@ namespace Service::Nvidia::Devices {
class nvmap final : public nvdevice { class nvmap final : public nvdevice {
public: public:
nvmap(Core::System& system); explicit nvmap(Core::System& system);
~nvmap() override; ~nvmap() override;
/// Returns the allocated address of an nvmap object given its handle. /// Returns the allocated address of an nvmap object given its handle.

View file

@ -100,11 +100,11 @@ void Module::SignalSyncpt(const u32 syncpoint_id, const u32 value) {
} }
} }
Kernel::SharedPtr<Kernel::ReadableEvent> Module::GetEvent(const u32 event_id) { Kernel::SharedPtr<Kernel::ReadableEvent> Module::GetEvent(const u32 event_id) const {
return events_interface.events[event_id].readable; return events_interface.events[event_id].readable;
} }
Kernel::SharedPtr<Kernel::WritableEvent> Module::GetEventWriteable(const u32 event_id) { Kernel::SharedPtr<Kernel::WritableEvent> Module::GetEventWriteable(const u32 event_id) const {
return events_interface.events[event_id].writable; return events_interface.events[event_id].writable;
} }

View file

@ -26,14 +26,15 @@ namespace Devices {
class nvdevice; class nvdevice;
} }
struct EventsInterface { struct EventInterface {
u64 events_mask{}; u64 events_mask{};
std::array<Kernel::EventPair, MaxNvEvents> events; std::array<Kernel::EventPair, MaxNvEvents> events;
std::array<EventState, MaxNvEvents> status{}; std::array<EventState, MaxNvEvents> status{};
std::array<bool, MaxNvEvents> registered{}; std::array<bool, MaxNvEvents> registered{};
std::array<u32, MaxNvEvents> assigned_syncpt{}; std::array<u32, MaxNvEvents> assigned_syncpt{};
std::array<u32, MaxNvEvents> assigned_value{}; std::array<u32, MaxNvEvents> assigned_value{};
u32 GetFreeEvent() { static constexpr u32 null_event = 0xFFFFFFFF;
u32 GetFreeEvent() const {
u64 mask = events_mask; u64 mask = events_mask;
for (u32 i = 0; i < MaxNvEvents; i++) { for (u32 i = 0; i < MaxNvEvents; i++) {
const bool is_free = (mask & 0x1) == 0; const bool is_free = (mask & 0x1) == 0;
@ -44,12 +45,13 @@ struct EventsInterface {
} }
mask = mask >> 1; mask = mask >> 1;
} }
return 0xFFFFFFFF; return null_event;
} }
void SetEventStatus(const u32 event_id, EventState new_status) { void SetEventStatus(const u32 event_id, EventState new_status) {
EventState old_status = status[event_id]; EventState old_status = status[event_id];
if (old_status == new_status) if (old_status == new_status) {
return; return;
}
status[event_id] = new_status; status[event_id] = new_status;
if (new_status == EventState::Registered) { if (new_status == EventState::Registered) {
registered[event_id] = true; registered[event_id] = true;
@ -102,9 +104,9 @@ public:
void SignalSyncpt(const u32 syncpoint_id, const u32 value); void SignalSyncpt(const u32 syncpoint_id, const u32 value);
Kernel::SharedPtr<Kernel::ReadableEvent> GetEvent(const u32 event_id); Kernel::SharedPtr<Kernel::ReadableEvent> GetEvent(u32 event_id) const;
Kernel::SharedPtr<Kernel::WritableEvent> GetEventWriteable(const u32 event_id); Kernel::SharedPtr<Kernel::WritableEvent> GetEventWriteable(u32 event_id) const;
private: private:
/// Id to use for the next open file descriptor. /// Id to use for the next open file descriptor.
@ -116,7 +118,7 @@ private:
/// Mapping of device node names to their implementation. /// Mapping of device node names to their implementation.
std::unordered_map<std::string, std::shared_ptr<Devices::nvdevice>> devices; std::unordered_map<std::string, std::shared_ptr<Devices::nvdevice>> devices;
EventsInterface events_interface; EventInterface events_interface;
}; };
/// Registers all NVDRV services with the specified service manager. /// Registers all NVDRV services with the specified service manager.

View file

@ -79,7 +79,7 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
} }
std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() {
std::vector<Buffer>::iterator itr = queue.end(); auto itr = queue.end();
while (itr == queue.end() && !queue_sequence.empty()) { while (itr == queue.end() && !queue_sequence.empty()) {
u32 slot = queue_sequence.front(); u32 slot = queue_sequence.front();
itr = std::find_if(queue.begin(), queue.end(), [&slot](const Buffer& buffer) { itr = std::find_if(queue.begin(), queue.end(), [&slot](const Buffer& buffer) {

View file

@ -37,8 +37,6 @@ NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_t
displays.emplace_back(4, "Null"); displays.emplace_back(4, "Null");
// Schedule the screen composition events // Schedule the screen composition events
// const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : frame_ticks;
composition_event = core_timing.RegisterEvent("ScreenComposition", [this](u64 userdata, composition_event = core_timing.RegisterEvent("ScreenComposition", [this](u64 userdata,
s64 cycles_late) { s64 cycles_late) {
Compose(); Compose();
@ -212,8 +210,9 @@ void NVFlinger::Compose() {
} }
} }
s64 NVFlinger::GetNextTicks() { s64 NVFlinger::GetNextTicks() const {
return (Core::Timing::BASE_CLOCK_RATE * (1LL << swap_interval)) / 120; constexpr s64 max_hertz = 120LL;
return (Core::Timing::BASE_CLOCK_RATE * (1LL << swap_interval)) / max_hertz;
} }
} // namespace Service::NVFlinger } // namespace Service::NVFlinger

View file

@ -74,7 +74,7 @@ public:
/// finished. /// finished.
void Compose(); void Compose();
s64 GetNextTicks(); s64 GetNextTicks() const;
private: private:
/// Finds the display identified by the specified ID. /// Finds the display identified by the specified ID.

View file

@ -89,24 +89,27 @@ u32 GPU::GetSyncpointValue(const u32 syncpoint_id) const {
} }
void GPU::RegisterSyncptInterrupt(const u32 syncpoint_id, const u32 value) { void GPU::RegisterSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
for (u32 in_value : syncpt_interrupts[syncpoint_id]) { auto& interrupt = syncpt_interrupts[syncpoint_id];
if (in_value == value) bool contains = std::any_of(interrupt.begin(), interrupt.end(),
return; [value](u32 in_value) { return in_value == value; });
if (contains) {
return;
} }
syncpt_interrupts[syncpoint_id].emplace_back(value); syncpt_interrupts[syncpoint_id].emplace_back(value);
} }
bool GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) { bool GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
std::lock_guard lock{sync_mutex}; std::lock_guard lock{sync_mutex};
auto it = syncpt_interrupts[syncpoint_id].begin(); auto& interrupt = syncpt_interrupts[syncpoint_id];
while (it != syncpt_interrupts[syncpoint_id].end()) { const auto iter =
if (value == *it) { std::find_if(interrupt.begin(), interrupt.end(),
it = syncpt_interrupts[syncpoint_id].erase(it); [value](u32 interrupt_value) { return value == interrupt_value; });
return true;
} if (iter == interrupt.end()) {
it++; return false;
} }
return false; interrupt.erase(iter);
return true;
} }
u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {

View file

@ -168,20 +168,16 @@ public:
/// Returns a reference to the GPU DMA pusher. /// Returns a reference to the GPU DMA pusher.
Tegra::DmaPusher& DmaPusher(); Tegra::DmaPusher& DmaPusher();
void IncrementSyncPoint(const u32 syncpoint_id); void IncrementSyncPoint(u32 syncpoint_id);
u32 GetSyncpointValue(const u32 syncpoint_id) const; u32 GetSyncpointValue(u32 syncpoint_id) const;
void RegisterSyncptInterrupt(const u32 syncpoint_id, const u32 value); void RegisterSyncptInterrupt(u32 syncpoint_id, u32 value);
bool CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value); bool CancelSyncptInterrupt(u32 syncpoint_id, u32 value);
void Guard(bool guard_set) { std::unique_lock<std::mutex> LockSync() {
if (guard_set) { return std::unique_lock{sync_mutex};
sync_mutex.lock();
} else {
sync_mutex.unlock();
}
} }
bool IsAsync() const { bool IsAsync() const {
@ -253,7 +249,7 @@ public:
virtual void FlushAndInvalidateRegion(CacheAddr addr, u64 size) = 0; virtual void FlushAndInvalidateRegion(CacheAddr addr, u64 size) = 0;
protected: protected:
virtual void TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const = 0; virtual void TriggerCpuInterrupt(u32 syncpoint_id, u32 value) const = 0;
private: private:
void ProcessBindMethod(const MethodCall& method_call); void ProcessBindMethod(const MethodCall& method_call);

View file

@ -28,7 +28,7 @@ public:
void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override;
protected: protected:
void TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const override; void TriggerCpuInterrupt(u32 syncpoint_id, u32 value) const override;
private: private:
GPUThread::ThreadManager gpu_thread; GPUThread::ThreadManager gpu_thread;

View file

@ -27,7 +27,8 @@ public:
void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override;
protected: protected:
void TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const override {} void TriggerCpuInterrupt([[maybe_unused]] u32 syncpoint_id,
[[maybe_unused]] u32 value) const override {}
}; };
} // namespace VideoCommon } // namespace VideoCommon