mirror of
https://github.com/Takiiiiiiii/strato.git
synced 2025-07-17 08:46:39 +00:00
Apply GPU readback hack to both buffers and textures
And rename as appropriate.
This commit is contained in:
@ -5,6 +5,7 @@
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/types/KProcess.h>
|
||||
#include <common/trace.h>
|
||||
#include <common/settings.h>
|
||||
#include "buffer.h"
|
||||
|
||||
namespace skyline::gpu {
|
||||
@ -38,8 +39,14 @@ namespace skyline::gpu {
|
||||
// If this mutex would cause other callbacks to be blocked then we should block on this mutex in advance
|
||||
std::shared_ptr<FenceCycle> waitCycle{};
|
||||
do {
|
||||
if (waitCycle)
|
||||
if (waitCycle) {
|
||||
i64 startNs{buffer->accumulatedGuestWaitCounter > FastReadbackHackWaitCountThreshold ? util::GetTimeNs() : 0};
|
||||
waitCycle->Wait();
|
||||
if (startNs)
|
||||
buffer->accumulatedGuestWaitTime += std::chrono::nanoseconds(util::GetTimeNs() - startNs);
|
||||
|
||||
buffer->accumulatedGuestWaitCounter++;
|
||||
}
|
||||
|
||||
std::scoped_lock lock{*buffer};
|
||||
if (waitCycle && buffer->cycle == waitCycle) {
|
||||
@ -89,6 +96,14 @@ namespace skyline::gpu {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (buffer->accumulatedGuestWaitTime > FastReadbackHackWaitTimeThreshold && *buffer->gpu.state.settings->enableFastGpuReadbackHack) {
|
||||
// As opposed to skipping readback as we do for textures, with buffers we can still perform the readback but just without syncinc the GPU
|
||||
// While the read data may be invalid it's still better than nothing and works in most cases
|
||||
memcpy(buffer->mirror.data(), buffer->backing.data(), buffer->mirror.size());
|
||||
buffer->dirtyState = DirtyState::Clean;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_lock lock{*buffer, std::try_to_lock};
|
||||
if (!lock)
|
||||
return false;
|
||||
|
@ -90,6 +90,11 @@ namespace skyline::gpu {
|
||||
static constexpr size_t FrequentlyLockedThreshold{2}; //!< Threshold for the number of times a buffer can be locked (not from context locks, only normal) before it should be considered frequently locked
|
||||
size_t accumulatedCpuLockCounter{}; //!< Number of times buffer has been locked through non-ContextLocks
|
||||
|
||||
static constexpr size_t FastReadbackHackWaitCountThreshold{8}; //!< Threshold for the number of times a buffer can be waited on before it should be considered for the readback hack
|
||||
static constexpr std::chrono::nanoseconds FastReadbackHackWaitTimeThreshold{constant::NsInSecond / 2}; //!< Threshold for the amount of time buffer texture can be waited on before it should be considered for the readback hack, `SkipReadbackHackWaitCountThreshold` needs to be hit before this
|
||||
size_t accumulatedGuestWaitCounter{}; //!< Total number of times the buffer has been waited on
|
||||
std::chrono::nanoseconds accumulatedGuestWaitTime{}; //!< Amount of time the buffer has been waited on for since the `FastReadbackHackWaitTimeThreshold`th wait on it by the guest
|
||||
|
||||
/**
|
||||
* @brief Resets all megabuffer tracking state
|
||||
*/
|
||||
|
@ -225,7 +225,7 @@ namespace skyline::gpu {
|
||||
return true; // If the texture is already CPU dirty or we can transition it to being CPU dirty then we don't need to do anything
|
||||
}
|
||||
|
||||
if (texture->accumulatedGuestWaitTime > SkipReadbackHackWaitTimeThreshold && *texture->gpu.state.settings->enableTextureReadbackHack) {
|
||||
if (texture->accumulatedGuestWaitTime > SkipReadbackHackWaitTimeThreshold && *texture->gpu.state.settings->enableFastGpuReadbackHack) {
|
||||
texture->dirtyState = DirtyState::Clean;
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user