mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-22 23:02:47 +01:00
NVServices: Styling, define constructors as explicit and corrections
This commit is contained in:
parent
b391e5f638
commit
d20ede40b1
24 changed files with 73 additions and 65 deletions
|
@ -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_timing.h"
|
||||
#include "core/hardware_interrupt_manager.h"
|
||||
#include "core/hle/service/nvdrv/interface.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) {
|
||||
auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv");
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
InterruptManager::~InterruptManager() = default;
|
||||
|
||||
void InterruptManager::GPUInterruptSyncpt(const u32 syncpoint_id, const u32 value) {
|
||||
const u64 msg = (static_cast<u64>(syncpoint_id) << 32ULL) | value;
|
||||
system.CoreTiming().ScheduleEvent(10, gpu_interrupt_event, msg);
|
||||
|
|
|
@ -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
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/core_timing.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Core::Timing {
|
||||
struct EventType;
|
||||
}
|
||||
|
||||
namespace Core::Hardware {
|
||||
|
||||
class InterruptManager {
|
||||
public:
|
||||
InterruptManager(Core::System& system);
|
||||
~InterruptManager() = default;
|
||||
explicit InterruptManager(Core::System& system);
|
||||
~InterruptManager();
|
||||
|
||||
void GPUInterruptSyncpt(const u32 syncpoint_id, const u32 value);
|
||||
void GPUInterruptSyncpt(u32 syncpoint_id, u32 value);
|
||||
|
||||
private:
|
||||
Core::System& system;
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Service::Nvidia::Devices {
|
|||
/// implement the ioctl interface.
|
||||
class nvdevice {
|
||||
public:
|
||||
nvdevice(Core::System& system) : system{system} {};
|
||||
explicit nvdevice(Core::System& system) : system{system} {};
|
||||
virtual ~nvdevice() = default;
|
||||
union Ioctl {
|
||||
u32_le raw;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
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} {}
|
||||
nvhost_ctrl::~nvhost_ctrl() = default;
|
||||
|
||||
|
@ -67,12 +67,11 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
|
|||
if (!gpu.IsAsync()) {
|
||||
return NvResult::Success;
|
||||
}
|
||||
gpu.Guard(true);
|
||||
auto lock = gpu.LockSync();
|
||||
u32 current_syncpoint_value = gpu.GetSyncpointValue(params.syncpt_id);
|
||||
if (current_syncpoint_value >= params.threshold) {
|
||||
params.value = current_syncpoint_value;
|
||||
std::memcpy(output.data(), ¶ms, sizeof(params));
|
||||
gpu.Guard(false);
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
|
@ -82,7 +81,6 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
|
|||
|
||||
if (params.timeout == 0) {
|
||||
std::memcpy(output.data(), ¶ms, sizeof(params));
|
||||
gpu.Guard(false);
|
||||
return NvResult::Timeout;
|
||||
}
|
||||
|
||||
|
@ -91,7 +89,6 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
|
|||
event_id = params.value & 0x00FF;
|
||||
if (event_id >= 64) {
|
||||
std::memcpy(output.data(), ¶ms, sizeof(params));
|
||||
gpu.Guard(false);
|
||||
return NvResult::BadParameter;
|
||||
}
|
||||
} else {
|
||||
|
@ -119,15 +116,12 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
|
|||
ctrl.must_delay = true;
|
||||
ctrl.timeout = params.timeout;
|
||||
ctrl.event_id = event_id;
|
||||
gpu.Guard(false);
|
||||
return NvResult::Timeout;
|
||||
}
|
||||
std::memcpy(output.data(), ¶ms, sizeof(params));
|
||||
gpu.Guard(false);
|
||||
return NvResult::Timeout;
|
||||
}
|
||||
std::memcpy(output.data(), ¶ms, sizeof(params));
|
||||
gpu.Guard(false);
|
||||
return NvResult::BadParameter;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace Service::Nvidia::Devices {
|
|||
|
||||
class nvhost_ctrl final : public nvdevice {
|
||||
public:
|
||||
nvhost_ctrl(Core::System& system, EventsInterface& events_interface);
|
||||
explicit nvhost_ctrl(Core::System& system, EventInterface& events_interface);
|
||||
~nvhost_ctrl() override;
|
||||
|
||||
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);
|
||||
|
||||
EventsInterface& events_interface;
|
||||
EventInterface& events_interface;
|
||||
};
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
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;
|
||||
|
||||
u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Service::Nvidia::Devices {
|
|||
|
||||
class nvhost_ctrl_gpu final : public nvdevice {
|
||||
public:
|
||||
nvhost_ctrl_gpu(Core::System& system);
|
||||
explicit nvhost_ctrl_gpu(Core::System& system);
|
||||
~nvhost_ctrl_gpu() override;
|
||||
|
||||
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
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;
|
||||
|
||||
u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Service::Nvidia::Devices {
|
|||
|
||||
class nvhost_nvdec final : public nvdevice {
|
||||
public:
|
||||
nvhost_nvdec(Core::System& system);
|
||||
explicit nvhost_nvdec(Core::System& system);
|
||||
~nvhost_nvdec() override;
|
||||
|
||||
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
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;
|
||||
|
||||
u32 nvhost_nvjpg::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Service::Nvidia::Devices {
|
|||
|
||||
class nvhost_nvjpg final : public nvdevice {
|
||||
public:
|
||||
nvhost_nvjpg(Core::System& system);
|
||||
explicit nvhost_nvjpg(Core::System& system);
|
||||
~nvhost_nvjpg() override;
|
||||
|
||||
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
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;
|
||||
|
||||
u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Service::Nvidia::Devices {
|
|||
|
||||
class nvhost_vic final : public nvdevice {
|
||||
public:
|
||||
nvhost_vic(Core::System& system);
|
||||
explicit nvhost_vic(Core::System& system);
|
||||
~nvhost_vic() override;
|
||||
|
||||
u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
|
||||
|
|
|
@ -18,7 +18,7 @@ enum {
|
|||
};
|
||||
}
|
||||
|
||||
nvmap::nvmap(Core::System& system) : nvdevice(system){};
|
||||
nvmap::nvmap(Core::System& system) : nvdevice(system) {}
|
||||
nvmap::~nvmap() = default;
|
||||
|
||||
VAddr nvmap::GetObjectAddress(u32 handle) const {
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Service::Nvidia::Devices {
|
|||
|
||||
class nvmap final : public nvdevice {
|
||||
public:
|
||||
nvmap(Core::System& system);
|
||||
explicit nvmap(Core::System& system);
|
||||
~nvmap() override;
|
||||
|
||||
/// Returns the allocated address of an nvmap object given its handle.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,14 +26,15 @@ namespace Devices {
|
|||
class nvdevice;
|
||||
}
|
||||
|
||||
struct EventsInterface {
|
||||
struct EventInterface {
|
||||
u64 events_mask{};
|
||||
std::array<Kernel::EventPair, MaxNvEvents> events;
|
||||
std::array<EventState, MaxNvEvents> status{};
|
||||
std::array<bool, MaxNvEvents> registered{};
|
||||
std::array<u32, MaxNvEvents> assigned_syncpt{};
|
||||
std::array<u32, MaxNvEvents> assigned_value{};
|
||||
u32 GetFreeEvent() {
|
||||
static constexpr u32 null_event = 0xFFFFFFFF;
|
||||
u32 GetFreeEvent() const {
|
||||
u64 mask = events_mask;
|
||||
for (u32 i = 0; i < MaxNvEvents; i++) {
|
||||
const bool is_free = (mask & 0x1) == 0;
|
||||
|
@ -44,12 +45,13 @@ struct EventsInterface {
|
|||
}
|
||||
mask = mask >> 1;
|
||||
}
|
||||
return 0xFFFFFFFF;
|
||||
return null_event;
|
||||
}
|
||||
void SetEventStatus(const u32 event_id, EventState new_status) {
|
||||
EventState old_status = status[event_id];
|
||||
if (old_status == new_status)
|
||||
if (old_status == new_status) {
|
||||
return;
|
||||
}
|
||||
status[event_id] = new_status;
|
||||
if (new_status == EventState::Registered) {
|
||||
registered[event_id] = true;
|
||||
|
@ -102,9 +104,9 @@ public:
|
|||
|
||||
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:
|
||||
/// Id to use for the next open file descriptor.
|
||||
|
@ -116,7 +118,7 @@ private:
|
|||
/// Mapping of device node names to their implementation.
|
||||
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.
|
||||
|
|
|
@ -79,7 +79,7 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
|
|||
}
|
||||
|
||||
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()) {
|
||||
u32 slot = queue_sequence.front();
|
||||
itr = std::find_if(queue.begin(), queue.end(), [&slot](const Buffer& buffer) {
|
||||
|
|
|
@ -37,8 +37,6 @@ NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_t
|
|||
displays.emplace_back(4, "Null");
|
||||
|
||||
// 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,
|
||||
s64 cycles_late) {
|
||||
Compose();
|
||||
|
@ -212,8 +210,9 @@ void NVFlinger::Compose() {
|
|||
}
|
||||
}
|
||||
|
||||
s64 NVFlinger::GetNextTicks() {
|
||||
return (Core::Timing::BASE_CLOCK_RATE * (1LL << swap_interval)) / 120;
|
||||
s64 NVFlinger::GetNextTicks() const {
|
||||
constexpr s64 max_hertz = 120LL;
|
||||
return (Core::Timing::BASE_CLOCK_RATE * (1LL << swap_interval)) / max_hertz;
|
||||
}
|
||||
|
||||
} // namespace Service::NVFlinger
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
/// finished.
|
||||
void Compose();
|
||||
|
||||
s64 GetNextTicks();
|
||||
s64 GetNextTicks() const;
|
||||
|
||||
private:
|
||||
/// Finds the display identified by the specified ID.
|
||||
|
|
|
@ -89,24 +89,27 @@ u32 GPU::GetSyncpointValue(const u32 syncpoint_id) const {
|
|||
}
|
||||
|
||||
void GPU::RegisterSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
|
||||
for (u32 in_value : syncpt_interrupts[syncpoint_id]) {
|
||||
if (in_value == value)
|
||||
return;
|
||||
auto& interrupt = syncpt_interrupts[syncpoint_id];
|
||||
bool contains = std::any_of(interrupt.begin(), interrupt.end(),
|
||||
[value](u32 in_value) { return in_value == value; });
|
||||
if (contains) {
|
||||
return;
|
||||
}
|
||||
syncpt_interrupts[syncpoint_id].emplace_back(value);
|
||||
}
|
||||
|
||||
bool GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
|
||||
std::lock_guard lock{sync_mutex};
|
||||
auto it = syncpt_interrupts[syncpoint_id].begin();
|
||||
while (it != syncpt_interrupts[syncpoint_id].end()) {
|
||||
if (value == *it) {
|
||||
it = syncpt_interrupts[syncpoint_id].erase(it);
|
||||
return true;
|
||||
}
|
||||
it++;
|
||||
auto& interrupt = syncpt_interrupts[syncpoint_id];
|
||||
const auto iter =
|
||||
std::find_if(interrupt.begin(), interrupt.end(),
|
||||
[value](u32 interrupt_value) { return value == interrupt_value; });
|
||||
|
||||
if (iter == interrupt.end()) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
interrupt.erase(iter);
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
|
||||
|
|
|
@ -168,20 +168,16 @@ public:
|
|||
/// Returns a reference to the GPU DMA pusher.
|
||||
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) {
|
||||
if (guard_set) {
|
||||
sync_mutex.lock();
|
||||
} else {
|
||||
sync_mutex.unlock();
|
||||
}
|
||||
std::unique_lock<std::mutex> LockSync() {
|
||||
return std::unique_lock{sync_mutex};
|
||||
}
|
||||
|
||||
bool IsAsync() const {
|
||||
|
@ -253,7 +249,7 @@ public:
|
|||
virtual void FlushAndInvalidateRegion(CacheAddr addr, u64 size) = 0;
|
||||
|
||||
protected:
|
||||
virtual void TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const = 0;
|
||||
virtual void TriggerCpuInterrupt(u32 syncpoint_id, u32 value) const = 0;
|
||||
|
||||
private:
|
||||
void ProcessBindMethod(const MethodCall& method_call);
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override;
|
||||
|
||||
protected:
|
||||
void TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const override;
|
||||
void TriggerCpuInterrupt(u32 syncpoint_id, u32 value) const override;
|
||||
|
||||
private:
|
||||
GPUThread::ThreadManager gpu_thread;
|
||||
|
|
|
@ -27,7 +27,8 @@ public:
|
|||
void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override;
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue