skyline/app/src/main/cpp/skyline/soc/host1x/syncpoint.h
PixelyIon 216e5cee81 Separate Guest and Host Presentation + AChoreographer V-Sync Event
We had issues when combining host and guest presentation since certain configurations in guest presentation such as double buffering were very unoptimal for the host and would significantly affect the FPS. As a result of this, we've now made host presentation have its own presentation textures which are copied into from the guest at presentation time, allowing us to change parameters of the host presentation independently of the guest.

We've implemented the infrastructure for this which includes being able to create images from host GPU memory using VMA, an optimized linear texture sync and a method to do on-GPU texture-to-texture copies.

We've also moved to driving the V-Sync event using AChoreographer on its on thread in this PR, which more accurately encapsulates HOS behavior and allows games such as ARMS to boot as they depend on the V-Sync event being signalled even when the game isn't presenting.
2021-07-12 21:27:49 +05:30

55 lines
2.0 KiB
C++

// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
// Copyright © 2020 Ryujinx Team and Contributors
#pragma once
#include <common.h>
namespace skyline::soc::host1x {
constexpr size_t SyncpointCount{192}; //!< The number of host1x syncpoints on T210
/**
* @brief The Syncpoint class represents a single syncpoint in the GPU which is used for GPU -> CPU synchronisation
*/
class Syncpoint {
private:
struct Waiter {
u32 threshold; //!< The syncpoint value to wait on to be reached
std::function<void()> callback; //!< The callback to do after the wait has ended
};
std::mutex waiterLock; //!< Synchronizes insertions and deletions of waiters
std::map<u64, Waiter> waiterMap;
u64 nextWaiterId{1};
public:
std::atomic<u32> value{};
/**
* @brief Registers a new waiter with a callback that will be called when the syncpoint reaches the target threshold
* @note The callback will be called immediately if the syncpoint has already reached the given threshold
* @return A persistent identifier that can be used to refer to the waiter, or 0 if the threshold has already been reached
*/
u64 RegisterWaiter(u32 threshold, const std::function<void()> &callback);
/**
* @brief Removes a waiter given by 'id' from the pending waiter map
*/
void DeregisterWaiter(u64 id);
/**
* @brief Increments the syncpoint by 1
* @return The new value of the syncpoint
*/
u32 Increment();
/**
* @brief Waits for the syncpoint to reach given threshold
* @return If the wait was successful (true) or timed out (false)
* @note Guaranteed to succeed when 'steady_clock::duration::max()' is used
*/
bool Wait(u32 threshold, std::chrono::steady_clock::duration timeout);
};
}