mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-30 05:50:05 +00:00
test
This commit is contained in:
parent
a81536f53f
commit
dcea128d80
@ -3,6 +3,7 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "audio_core/audio_core.h"
|
#include "audio_core/audio_core.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
@ -26,6 +27,11 @@ namespace Core {
|
|||||||
|
|
||||||
/*static*/ System System::s_instance;
|
/*static*/ System System::s_instance;
|
||||||
|
|
||||||
|
std::thread CpuThread;
|
||||||
|
std::atomic<bool> CpuThreadRunning;
|
||||||
|
std::atomic<bool> RunCPU;
|
||||||
|
std::atomic<int> TightLoop;
|
||||||
|
|
||||||
System::ResultStatus System::RunLoop(int tight_loop) {
|
System::ResultStatus System::RunLoop(int tight_loop) {
|
||||||
status = ResultStatus::Success;
|
status = ResultStatus::Success;
|
||||||
if (!cpu_core) {
|
if (!cpu_core) {
|
||||||
@ -47,6 +53,15 @@ System::ResultStatus System::RunLoop(int tight_loop) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TightLoop += tight_loop;
|
||||||
|
RunCPU = true;
|
||||||
|
|
||||||
|
HW::Update();
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void System::RunLoopInner() {
|
||||||
// If we don't have a currently active thread then don't execute instructions,
|
// If we don't have a currently active thread then don't execute instructions,
|
||||||
// instead advance to the next event and try to yield to the next thread
|
// instead advance to the next event and try to yield to the next thread
|
||||||
if (Kernel::GetCurrentThread() == nullptr) {
|
if (Kernel::GetCurrentThread() == nullptr) {
|
||||||
@ -55,13 +70,20 @@ System::ResultStatus System::RunLoop(int tight_loop) {
|
|||||||
CoreTiming::Advance();
|
CoreTiming::Advance();
|
||||||
PrepareReschedule();
|
PrepareReschedule();
|
||||||
} else {
|
} else {
|
||||||
cpu_core->Run(tight_loop);
|
cpu_core->Run(TightLoop);
|
||||||
}
|
}
|
||||||
|
|
||||||
HW::Update();
|
TightLoop = 0;
|
||||||
Reschedule();
|
Reschedule();
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
void System::RunLoopInThread() {
|
||||||
|
while (CpuThreadRunning) {
|
||||||
|
if (RunCPU) {
|
||||||
|
RunLoopInner();
|
||||||
|
RunCPU = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System::ResultStatus System::SingleStep() {
|
System::ResultStatus System::SingleStep() {
|
||||||
@ -164,10 +186,16 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
|
|||||||
GetAndResetPerfStats();
|
GetAndResetPerfStats();
|
||||||
perf_stats.BeginSystemFrame();
|
perf_stats.BeginSystemFrame();
|
||||||
|
|
||||||
|
CpuThreadRunning = true;
|
||||||
|
CpuThread = std::thread(&System::RunLoopInThread, this);
|
||||||
|
|
||||||
return ResultStatus::Success;
|
return ResultStatus::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::Shutdown() {
|
void System::Shutdown() {
|
||||||
|
CpuThreadRunning = false;
|
||||||
|
CpuThread.join();
|
||||||
|
|
||||||
// Log last frame performance stats
|
// Log last frame performance stats
|
||||||
auto perf_results = GetAndResetPerfStats();
|
auto perf_results = GetAndResetPerfStats();
|
||||||
Telemetry().AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed",
|
Telemetry().AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed",
|
||||||
|
@ -54,6 +54,8 @@ public:
|
|||||||
* @return Result status, indicating whethor or not the operation succeeded.
|
* @return Result status, indicating whethor or not the operation succeeded.
|
||||||
*/
|
*/
|
||||||
ResultStatus RunLoop(int tight_loop = 1000);
|
ResultStatus RunLoop(int tight_loop = 1000);
|
||||||
|
void RunLoopInThread();
|
||||||
|
void RunLoopInner();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step the CPU one instruction
|
* Step the CPU one instruction
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <boost/lockfree/queue.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@ -28,6 +29,14 @@ namespace GPU {
|
|||||||
|
|
||||||
Regs g_regs;
|
Regs g_regs;
|
||||||
|
|
||||||
|
struct WriteThing {
|
||||||
|
u32 addr;
|
||||||
|
u32 data;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::atomic<bool> VBlankGo = false;
|
||||||
|
boost::lockfree::queue<WriteThing> WriteQueue(128);
|
||||||
|
|
||||||
/// 268MHz CPU clocks / 60Hz frames per second
|
/// 268MHz CPU clocks / 60Hz frames per second
|
||||||
const u64 frame_ticks = static_cast<u64>(BASE_CLOCK_RATE_ARM11 / SCREEN_REFRESH_RATE);
|
const u64 frame_ticks = static_cast<u64>(BASE_CLOCK_RATE_ARM11 / SCREEN_REFRESH_RATE);
|
||||||
/// Event id for CoreTiming
|
/// Event id for CoreTiming
|
||||||
@ -392,6 +401,11 @@ static void TextureCopy(const Regs::DisplayTransferConfig& config) {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void Write(u32 addr, const T data) {
|
inline void Write(u32 addr, const T data) {
|
||||||
|
WriteQueue.push(WriteThing{addr, static_cast<u32>(data)});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void WriteE(u32 addr, const T data) {
|
||||||
addr -= HW::VADDR_GPU;
|
addr -= HW::VADDR_GPU;
|
||||||
u32 index = addr / 4;
|
u32 index = addr / 4;
|
||||||
|
|
||||||
@ -515,8 +529,6 @@ template void Write<u8>(u32 addr, const u8 data);
|
|||||||
|
|
||||||
/// Update hardware
|
/// Update hardware
|
||||||
static void VBlankCallback(u64 userdata, int cycles_late) {
|
static void VBlankCallback(u64 userdata, int cycles_late) {
|
||||||
VideoCore::g_renderer->SwapBuffers();
|
|
||||||
|
|
||||||
// Signal to GSP that GPU interrupt has occurred
|
// Signal to GSP that GPU interrupt has occurred
|
||||||
// TODO(yuriks): hwtest to determine if PDC0 is for the Top screen and PDC1 for the Sub
|
// TODO(yuriks): hwtest to determine if PDC0 is for the Top screen and PDC1 for the Sub
|
||||||
// screen, or if both use the same interrupts and these two instead determine the
|
// screen, or if both use the same interrupts and these two instead determine the
|
||||||
@ -524,6 +536,7 @@ static void VBlankCallback(u64 userdata, int cycles_late) {
|
|||||||
// two different intervals.
|
// two different intervals.
|
||||||
Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC0);
|
Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC0);
|
||||||
Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC1);
|
Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC1);
|
||||||
|
VBlankGo = true;
|
||||||
|
|
||||||
// Reschedule recurrent event
|
// Reschedule recurrent event
|
||||||
CoreTiming::ScheduleEvent(frame_ticks - cycles_late, vblank_event);
|
CoreTiming::ScheduleEvent(frame_ticks - cycles_late, vblank_event);
|
||||||
@ -565,6 +578,17 @@ void Init() {
|
|||||||
LOG_DEBUG(HW_GPU, "initialized OK");
|
LOG_DEBUG(HW_GPU, "initialized OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Update() {
|
||||||
|
WriteThing thing;
|
||||||
|
while (WriteQueue.pop(thing)) {
|
||||||
|
WriteE<u32>(thing.addr, thing.data);
|
||||||
|
}
|
||||||
|
if (VBlankGo) {
|
||||||
|
VideoCore::g_renderer->SwapBuffers();
|
||||||
|
VBlankGo = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Shutdown hardware
|
/// Shutdown hardware
|
||||||
void Shutdown() {
|
void Shutdown() {
|
||||||
LOG_DEBUG(HW_GPU, "shutdown OK");
|
LOG_DEBUG(HW_GPU, "shutdown OK");
|
||||||
|
@ -328,6 +328,8 @@ void Write(u32 addr, const T data);
|
|||||||
/// Initialize hardware
|
/// Initialize hardware
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
/// Shutdown hardware
|
/// Shutdown hardware
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
|
@ -82,7 +82,9 @@ template void Write<u16>(u32 addr, const u16 data);
|
|||||||
template void Write<u8>(u32 addr, const u8 data);
|
template void Write<u8>(u32 addr, const u8 data);
|
||||||
|
|
||||||
/// Update hardware
|
/// Update hardware
|
||||||
void Update() {}
|
void Update() {
|
||||||
|
GPU::Update();
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialize hardware
|
/// Initialize hardware
|
||||||
void Init() {
|
void Init() {
|
||||||
|
Loading…
Reference in New Issue
Block a user