aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/gpu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/gpu.cpp')
-rw-r--r--src/video_core/gpu.cpp86
1 files changed, 57 insertions, 29 deletions
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 548a8bf809..a44015c0dd 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -10,6 +10,7 @@
#include <condition_variable>
#include <list>
#include <memory>
+#include <utility>
#include "common/assert.h"
#include "common/settings.h"
@@ -39,6 +40,19 @@
namespace Tegra {
+namespace {
+constexpr u64 GpuClockMultiplier(Settings::GpuClock clock) {
+ switch (clock) {
+ case Settings::GpuClock::Boost:
+ return 256;
+ case Settings::GpuClock::Overclock:
+ return 512;
+ default:
+ return 1;
+ }
+}
+} // Anonymous namespace
+
struct GPU::Impl {
explicit Impl(Core::System& system_, bool is_async_, bool use_nvdec_)
: system{system_}
@@ -116,7 +130,7 @@ struct GPU::Impl {
[[nodiscard]] u64 RequestSyncOperation(Func&& action) {
std::unique_lock lck{sync_request_mutex};
const u64 fence = ++last_sync_fence;
- sync_requests.emplace_back(action);
+ sync_requests.emplace_back(std::forward<Func>(action));
return fence;
}
@@ -145,14 +159,8 @@ struct GPU::Impl {
}
[[nodiscard]] u64 GetTicks() const {
- u64 gpu_tick = system.CoreTiming().GetGPUTicks();
- Settings::GpuOverclock overclock = Settings::values.fast_gpu_time.GetValue();
-
- if (overclock != Settings::GpuOverclock::Normal) {
- gpu_tick /= 256 * u64(overclock);
- }
-
- return gpu_tick;
+ const u64 gpu_tick = system.CoreTiming().GetGPUTicks();
+ return gpu_tick / GpuClockMultiplier(Settings::values.gpu_clock.GetValue());
}
void RendererFrameEndNotify() {
@@ -225,9 +233,9 @@ struct GPU::Impl {
}
void RequestComposite(std::vector<Tegra::FramebufferConfig>&& layers, std::vector<Service::Nvidia::NvFence>&& fences) {
- size_t num_fences{fences.size()};
+ const size_t num_fences{fences.size()};
size_t current_request_counter{};
- {
+ if (num_fences != 0) {
std::unique_lock<std::mutex> lk(request_swap_mutex);
if (free_swap_counters.empty()) {
current_request_counter = request_swap_counters.size();
@@ -238,27 +246,42 @@ struct GPU::Impl {
free_swap_counters.pop_front();
}
}
- const auto wait_fence = RequestSyncOperation([this, current_request_counter, &layers, &fences, num_fences] {
- auto& syncpoint_manager = system.Host1x().GetSyncpointManager();
- if (num_fences == 0) {
- renderer->Composite(layers);
- }
- const auto executer = [this, current_request_counter, layers_copy = layers]() {
- {
- std::unique_lock<std::mutex> lk(request_swap_mutex);
- if (--request_swap_counters[current_request_counter] != 0) {
- return;
+ pending_composite_fence = RequestSyncOperation(
+ [this, current_request_counter, num_fences, composite_layers = std::move(layers),
+ composite_fences = std::move(fences)] {
+ if (num_fences == 0) {
+ renderer->Composite(composite_layers);
+ return;
+ }
+ auto& syncpoint_manager = system.Host1x().GetSyncpointManager();
+ const auto executer = [this, current_request_counter, composite_layers]() {
+ {
+ std::unique_lock<std::mutex> lk(request_swap_mutex);
+ if (--request_swap_counters[current_request_counter] != 0) {
+ return;
+ }
+ free_swap_counters.push_back(current_request_counter);
}
- free_swap_counters.push_back(current_request_counter);
+ renderer->Composite(composite_layers);
+ };
+ for (size_t i = 0; i < num_fences; i++) {
+ syncpoint_manager.RegisterGuestAction(composite_fences[i].id,
+ composite_fences[i].value, executer);
}
- renderer->Composite(layers_copy);
- };
- for (size_t i = 0; i < num_fences; i++) {
- syncpoint_manager.RegisterGuestAction(fences[i].id, fences[i].value, executer);
- }
- });
+ });
gpu_thread.TickGPU(is_async);
- WaitForSyncOperation(wait_fence);
+ }
+
+ void WaitForComposite() {
+ const u64 fence = pending_composite_fence;
+ if (fence == 0) {
+ return;
+ }
+ pending_composite_fence = 0;
+ if (shutting_down.load(std::memory_order_relaxed)) {
+ return;
+ }
+ WaitForSyncOperation(fence);
}
std::vector<u8> GetAppletCaptureBuffer() {
@@ -311,6 +334,7 @@ struct GPU::Impl {
std::deque<size_t> free_swap_counters;
std::deque<size_t> request_swap_counters;
std::mutex request_swap_mutex;
+ u64 pending_composite_fence{};
};
GPU::GPU(Core::System& system, bool is_async, bool use_nvdec)
@@ -428,6 +452,10 @@ void GPU::RequestComposite(std::vector<Tegra::FramebufferConfig>&& layers,
impl->RequestComposite(std::move(layers), std::move(fences));
}
+void GPU::WaitForComposite() {
+ impl->WaitForComposite();
+}
+
std::vector<u8> GPU::GetAppletCaptureBuffer() {
return impl->GetAppletCaptureBuffer();
}