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_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);

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
#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;

View file

@ -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;

View file

@ -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(), &params, 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(), &params, 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(), &params, 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(), &params, sizeof(params));
gpu.Guard(false);
return NvResult::Timeout;
}
std::memcpy(output.data(), &params, sizeof(params));
gpu.Guard(false);
return NvResult::BadParameter;
}

View file

@ -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

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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 {

View file

@ -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.

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;
}
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;
}

View file

@ -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.

View file

@ -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) {

View file

@ -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

View file

@ -74,7 +74,7 @@ public:
/// finished.
void Compose();
s64 GetNextTicks();
s64 GetNextTicks() const;
private:
/// 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) {
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) {

View file

@ -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);

View file

@ -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;

View file

@ -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