GraphicsSystem Save/Restore
This commit is contained in:
parent
9ed81b6876
commit
6997970d52
|
@ -292,12 +292,15 @@ X_STATUS Emulator::LaunchStfsContainer(std::wstring path) {
|
|||
}
|
||||
|
||||
void Emulator::Pause() {
|
||||
auto lock = global_critical_region::AcquireDirect();
|
||||
if (paused_) {
|
||||
return;
|
||||
}
|
||||
paused_ = true;
|
||||
|
||||
// Don't hold the lock on this (so any waits follow through)
|
||||
graphics_system_->Pause();
|
||||
|
||||
auto lock = global_critical_region::AcquireDirect();
|
||||
auto threads =
|
||||
kernel_state()->object_table()->GetObjectsByType<kernel::XThread>(
|
||||
kernel::XObject::kTypeThread);
|
||||
|
@ -320,6 +323,8 @@ void Emulator::Resume() {
|
|||
paused_ = false;
|
||||
XELOGD("! EMULATOR RESUMED !");
|
||||
|
||||
graphics_system_->Resume();
|
||||
|
||||
auto threads =
|
||||
kernel_state()->object_table()->GetObjectsByType<kernel::XThread>(
|
||||
kernel::XObject::kTypeThread);
|
||||
|
@ -349,6 +354,7 @@ bool Emulator::SaveToFile(const std::wstring& path) {
|
|||
|
||||
// It's important we don't hold the global lock here! XThreads need to step
|
||||
// forward (possibly through guarded regions) without worry!
|
||||
graphics_system_->Save(&stream);
|
||||
kernel_state_->Save(&stream);
|
||||
memory_->Save(&stream);
|
||||
map->Close(stream.offset());
|
||||
|
@ -376,6 +382,9 @@ bool Emulator::RestoreFromFile(const std::wstring& path) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!graphics_system_->Restore(&stream)) {
|
||||
return false;
|
||||
}
|
||||
if (!kernel_state_->Restore(&stream)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "xenia/base/byte_stream.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/base/profiling.h"
|
||||
|
@ -163,6 +164,59 @@ void CommandProcessor::WorkerThreadMain() {
|
|||
ShutdownContext();
|
||||
}
|
||||
|
||||
void CommandProcessor::Pause() {
|
||||
if (paused_) {
|
||||
return;
|
||||
}
|
||||
paused_ = true;
|
||||
|
||||
threading::Fence fence;
|
||||
CallInThread([&fence]() {
|
||||
fence.Signal();
|
||||
threading::Thread::GetCurrentThread()->Suspend();
|
||||
});
|
||||
|
||||
// HACK - Prevents a hang in IssueSwap()
|
||||
swap_state_.pending = false;
|
||||
|
||||
fence.Wait();
|
||||
}
|
||||
|
||||
void CommandProcessor::Resume() {
|
||||
if (!paused_) {
|
||||
return;
|
||||
}
|
||||
paused_ = false;
|
||||
|
||||
worker_thread_->thread()->Resume();
|
||||
}
|
||||
|
||||
bool CommandProcessor::Save(ByteStream* stream) {
|
||||
assert_true(paused_);
|
||||
|
||||
stream->Write<uint32_t>(primary_buffer_ptr_);
|
||||
stream->Write<uint32_t>(primary_buffer_size_);
|
||||
stream->Write<uint32_t>(read_ptr_index_);
|
||||
stream->Write<uint32_t>(read_ptr_update_freq_);
|
||||
stream->Write<uint32_t>(read_ptr_writeback_ptr_);
|
||||
stream->Write<uint32_t>(write_ptr_index_.load());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandProcessor::Restore(ByteStream* stream) {
|
||||
assert_true(paused_);
|
||||
|
||||
primary_buffer_ptr_ = stream->Read<uint32_t>();
|
||||
primary_buffer_size_ = stream->Read<uint32_t>();
|
||||
read_ptr_index_ = stream->Read<uint32_t>();
|
||||
read_ptr_update_freq_ = stream->Read<uint32_t>();
|
||||
read_ptr_writeback_ptr_ = stream->Read<uint32_t>();
|
||||
write_ptr_index_.store(stream->Read<uint32_t>());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandProcessor::SetupContext() { return true; }
|
||||
|
||||
void CommandProcessor::ShutdownContext() { context_.reset(); }
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#include "xenia/ui/graphics_context.h"
|
||||
|
||||
namespace xe {
|
||||
|
||||
class ByteStream;
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class GraphicsSystem;
|
||||
|
@ -91,6 +94,13 @@ class CommandProcessor {
|
|||
|
||||
void ExecutePacket(uint32_t ptr, uint32_t count);
|
||||
|
||||
bool is_paused() const { return paused_; }
|
||||
void Pause();
|
||||
void Resume();
|
||||
|
||||
bool Save(ByteStream* stream);
|
||||
bool Restore(ByteStream* stream);
|
||||
|
||||
protected:
|
||||
class RingbufferReader;
|
||||
|
||||
|
@ -214,6 +224,9 @@ class CommandProcessor {
|
|||
|
||||
Shader* active_vertex_shader_ = nullptr;
|
||||
Shader* active_pixel_shader_ = nullptr;
|
||||
|
||||
bool paused_ = false;
|
||||
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "xenia/gpu/graphics_system.h"
|
||||
|
||||
#include "xenia/base/byte_stream.h"
|
||||
#include "xenia/base/clock.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
|
@ -246,5 +247,31 @@ void GraphicsSystem::BeginTracing() {
|
|||
|
||||
void GraphicsSystem::EndTracing() { command_processor_->EndTracing(); }
|
||||
|
||||
void GraphicsSystem::Pause() {
|
||||
paused_ = true;
|
||||
|
||||
command_processor_->Pause();
|
||||
}
|
||||
|
||||
void GraphicsSystem::Resume() {
|
||||
paused_ = false;
|
||||
|
||||
command_processor_->Resume();
|
||||
}
|
||||
|
||||
bool GraphicsSystem::Save(ByteStream* stream) {
|
||||
stream->Write<uint32_t>(interrupt_callback_);
|
||||
stream->Write<uint32_t>(interrupt_callback_data_);
|
||||
|
||||
return command_processor_->Save(stream);
|
||||
}
|
||||
|
||||
bool GraphicsSystem::Restore(ByteStream* stream) {
|
||||
interrupt_callback_ = stream->Read<uint32_t>();
|
||||
interrupt_callback_data_ = stream->Read<uint32_t>();
|
||||
|
||||
return command_processor_->Restore(stream);
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
|
|
@ -61,6 +61,13 @@ class GraphicsSystem {
|
|||
void BeginTracing();
|
||||
void EndTracing();
|
||||
|
||||
bool is_paused() const { return paused_; }
|
||||
void Pause();
|
||||
void Resume();
|
||||
|
||||
bool Save(ByteStream* stream);
|
||||
bool Restore(ByteStream* stream);
|
||||
|
||||
protected:
|
||||
GraphicsSystem();
|
||||
|
||||
|
@ -90,6 +97,8 @@ class GraphicsSystem {
|
|||
|
||||
RegisterFile register_file_;
|
||||
std::unique_ptr<CommandProcessor> command_processor_;
|
||||
|
||||
bool paused_ = false;
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
|
|
Loading…
Reference in New Issue