mirror of https://github.com/yuzu-mirror/yuzu
Merge pull request #2592 from FernandoS27/sync1
Implement GPU Synchronization Mechanisms & Correct NVFlingerpull/8/head
commit
52f54c728d
@ -0,0 +1,30 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
namespace Core::Hardware {
|
||||||
|
|
||||||
|
InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) {
|
||||||
|
gpu_interrupt_event =
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Core::Hardware
|
@ -0,0 +1,31 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Core::Timing {
|
||||||
|
struct EventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Core::Hardware {
|
||||||
|
|
||||||
|
class InterruptManager {
|
||||||
|
public:
|
||||||
|
explicit InterruptManager(Core::System& system);
|
||||||
|
~InterruptManager();
|
||||||
|
|
||||||
|
void GPUInterruptSyncpt(u32 syncpoint_id, u32 value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Core::System& system;
|
||||||
|
Core::Timing::EventType* gpu_interrupt_event{};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core::Hardware
|
@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace Service::Nvidia {
|
||||||
|
|
||||||
|
constexpr u32 MaxSyncPoints = 192;
|
||||||
|
constexpr u32 MaxNvEvents = 64;
|
||||||
|
|
||||||
|
struct Fence {
|
||||||
|
s32 id;
|
||||||
|
u32 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(Fence) == 8, "Fence has wrong size");
|
||||||
|
|
||||||
|
struct MultiFence {
|
||||||
|
u32 num_fences;
|
||||||
|
std::array<Fence, 4> fences;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum NvResult : u32 {
|
||||||
|
Success = 0,
|
||||||
|
BadParameter = 4,
|
||||||
|
Timeout = 5,
|
||||||
|
ResourceError = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class EventState {
|
||||||
|
Free = 0,
|
||||||
|
Registered = 1,
|
||||||
|
Waiting = 2,
|
||||||
|
Busy = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IoctlCtrl {
|
||||||
|
// First call done to the servioce for services that call itself again after a call.
|
||||||
|
bool fresh_call{true};
|
||||||
|
// Tells the Ioctl Wrapper that it must delay the IPC response and send the thread to sleep
|
||||||
|
bool must_delay{};
|
||||||
|
// Timeout for the delay
|
||||||
|
s64 timeout{};
|
||||||
|
// NV Event Id
|
||||||
|
s32 event_id{-1};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Service::Nvidia
|
Loading…
Reference in New Issue