GPU: Implement a host based GPU Clock.

This commit is contained in:
Fernando Sahmkow
2019-07-05 23:38:34 -04:00
parent 772c86a260
commit dcc1b8c735
5 changed files with 97 additions and 1 deletions

View File

@@ -22,6 +22,8 @@ add_library(video_core STATIC
gpu.h
gpu_asynch.cpp
gpu_asynch.h
gpu_clock.cpp
gpu_clock.h
gpu_synch.cpp
gpu_synch.h
gpu_thread.cpp

View File

@@ -12,6 +12,7 @@
#include "video_core/engines/maxwell_3d.h"
#include "video_core/engines/maxwell_dma.h"
#include "video_core/gpu.h"
#include "video_core/gpu_clock.h"
#include "video_core/memory_manager.h"
#include "video_core/renderer_base.h"
@@ -29,7 +30,9 @@ u32 FramebufferConfig::BytesPerPixel(PixelFormat format) {
UNREACHABLE();
}
GPU::GPU(Core::System& system, VideoCore::RendererBase& renderer) : renderer{renderer} {
GPU::GPU(Core::System& system, VideoCore::RendererBase& renderer)
: renderer{renderer} {
clock = std::make_unique<Tegra::GPUClock>();
auto& rasterizer{renderer.Rasterizer()};
memory_manager = std::make_unique<Tegra::MemoryManager>(rasterizer);
dma_pusher = std::make_unique<Tegra::DmaPusher>(*this);
@@ -66,6 +69,14 @@ const DmaPusher& GPU::DmaPusher() const {
return *dma_pusher;
}
Tegra::GPUClock& GPU::GetClock() {
return *clock;
}
const Tegra::GPUClock& GPU::GetClock() const {
return *clock;
}
u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
ASSERT(format != RenderTargetFormat::NONE);

View File

@@ -80,6 +80,7 @@ u32 DepthFormatBytesPerPixel(DepthFormat format);
struct CommandListHeader;
class DebugContext;
class GPUClock;
/**
* Struct describing framebuffer configuration
@@ -167,6 +168,12 @@ public:
/// Returns a const reference to the GPU DMA pusher.
const Tegra::DmaPusher& DmaPusher() const;
/// Returns a reference to the GPU's Clock.
Tegra::GPUClock& GetClock();
/// Returns a const reference to the GPU's Clock.
const Tegra::GPUClock& GetClock() const;
struct Regs {
static constexpr size_t NUM_REGS = 0x100;
@@ -262,6 +269,8 @@ private:
std::unique_ptr<Engines::MaxwellDMA> maxwell_dma;
/// Inline memory engine
std::unique_ptr<Engines::KeplerMemory> kepler_memory;
std::unique_ptr<GPUClock> clock;
};
#define ASSERT_REG_POSITION(field_name, position) \

View File

@@ -0,0 +1,19 @@
// Copyright 2019 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/uint128.h"
#include "video_core/gpu_clock.h"
namespace Tegra {
GPUClock::GPUClock() = default;
GPUClock::~GPUClock() = default;
u64 GPUClock::GetTicks() const {
const u64 ns = GetNsTime().count();
const u128 middle = Common::Multiply64Into128(ns, gpu_clock);
return Common::Divide128On32(middle, 1000000000).first;
}
} // namespace Tegra

View File

@@ -0,0 +1,55 @@
// Copyright 2019 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <chrono>
#include "common/common_types.h"
namespace Tegra {
enum GPUClockProfiles : u64 {
Profile1 = 384000000,
Profile2 = 768000000,
Profile3 = 691200000,
Profile4 = 230400000,
Profile5 = 307000000,
Profile6 = 460800000,
};
class GPUClock {
public:
GPUClock();
~GPUClock();
std::chrono::nanoseconds GetNsTime() const {
Clock::time_point now = Clock::now();
return std::chrono::duration_cast<std::chrono::nanoseconds>(now - start_walltime);
}
std::chrono::microseconds GetUsTime() const {
Clock::time_point now = Clock::now();
return std::chrono::duration_cast<std::chrono::microseconds>(now - start_walltime);
}
std::chrono::milliseconds GetMsTime() const {
Clock::time_point now = Clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(now - start_walltime);
}
u64 GetTicks() const;
void SetGPUClock(const u64 new_clock) {
gpu_clock = new_clock;
}
private:
using Clock = std::chrono::system_clock;
Clock::time_point start_walltime = Clock::now();
u64 gpu_clock{GPUClockProfiles::Profile1};
};
} // namespace Tegra