mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-30 03:20:05 +00:00
test
This commit is contained in:
parent
a81536f53f
commit
dcea128d80
@ -3,6 +3,7 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include "audio_core/audio_core.h"
|
||||
#include "common/logging/log.h"
|
||||
@ -26,6 +27,11 @@ namespace Core {
|
||||
|
||||
/*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) {
|
||||
status = ResultStatus::Success;
|
||||
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,
|
||||
// instead advance to the next event and try to yield to the next thread
|
||||
if (Kernel::GetCurrentThread() == nullptr) {
|
||||
@ -55,13 +70,20 @@ System::ResultStatus System::RunLoop(int tight_loop) {
|
||||
CoreTiming::Advance();
|
||||
PrepareReschedule();
|
||||
} else {
|
||||
cpu_core->Run(tight_loop);
|
||||
cpu_core->Run(TightLoop);
|
||||
}
|
||||
|
||||
HW::Update();
|
||||
TightLoop = 0;
|
||||
Reschedule();
|
||||
}
|
||||
|
||||
return status;
|
||||
void System::RunLoopInThread() {
|
||||
while (CpuThreadRunning) {
|
||||
if (RunCPU) {
|
||||
RunLoopInner();
|
||||
RunCPU = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System::ResultStatus System::SingleStep() {
|
||||
@ -164,10 +186,16 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
|
||||
GetAndResetPerfStats();
|
||||
perf_stats.BeginSystemFrame();
|
||||
|
||||
CpuThreadRunning = true;
|
||||
CpuThread = std::thread(&System::RunLoopInThread, this);
|
||||
|
||||
return ResultStatus::Success;
|
||||
}
|
||||
|
||||
void System::Shutdown() {
|
||||
CpuThreadRunning = false;
|
||||
CpuThread.join();
|
||||
|
||||
// Log last frame performance stats
|
||||
auto perf_results = GetAndResetPerfStats();
|
||||
Telemetry().AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed",
|
||||
|
@ -54,6 +54,8 @@ public:
|
||||
* @return Result status, indicating whethor or not the operation succeeded.
|
||||
*/
|
||||
ResultStatus RunLoop(int tight_loop = 1000);
|
||||
void RunLoopInThread();
|
||||
void RunLoopInner();
|
||||
|
||||
/**
|
||||
* Step the CPU one instruction
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <boost/lockfree/queue.hpp>
|
||||
#include <cstring>
|
||||
#include <numeric>
|
||||
#include <type_traits>
|
||||
@ -28,6 +29,14 @@ namespace GPU {
|
||||
|
||||
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
|
||||
const u64 frame_ticks = static_cast<u64>(BASE_CLOCK_RATE_ARM11 / SCREEN_REFRESH_RATE);
|
||||
/// Event id for CoreTiming
|
||||
@ -392,6 +401,11 @@ static void TextureCopy(const Regs::DisplayTransferConfig& config) {
|
||||
|
||||
template <typename T>
|
||||
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;
|
||||
u32 index = addr / 4;
|
||||
|
||||
@ -515,8 +529,6 @@ template void Write<u8>(u32 addr, const u8 data);
|
||||
|
||||
/// Update hardware
|
||||
static void VBlankCallback(u64 userdata, int cycles_late) {
|
||||
VideoCore::g_renderer->SwapBuffers();
|
||||
|
||||
// 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
|
||||
// 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.
|
||||
Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC0);
|
||||
Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC1);
|
||||
VBlankGo = true;
|
||||
|
||||
// Reschedule recurrent event
|
||||
CoreTiming::ScheduleEvent(frame_ticks - cycles_late, vblank_event);
|
||||
@ -565,6 +578,17 @@ void Init() {
|
||||
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
|
||||
void Shutdown() {
|
||||
LOG_DEBUG(HW_GPU, "shutdown OK");
|
||||
|
@ -328,6 +328,8 @@ void Write(u32 addr, const T data);
|
||||
/// Initialize hardware
|
||||
void Init();
|
||||
|
||||
void Update();
|
||||
|
||||
/// Shutdown hardware
|
||||
void Shutdown();
|
||||
|
||||
|
@ -82,7 +82,9 @@ template void Write<u16>(u32 addr, const u16 data);
|
||||
template void Write<u8>(u32 addr, const u8 data);
|
||||
|
||||
/// Update hardware
|
||||
void Update() {}
|
||||
void Update() {
|
||||
GPU::Update();
|
||||
}
|
||||
|
||||
/// Initialize hardware
|
||||
void Init() {
|
||||
|
Loading…
Reference in New Issue
Block a user