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() {
|
void Emulator::Pause() {
|
||||||
auto lock = global_critical_region::AcquireDirect();
|
|
||||||
if (paused_) {
|
if (paused_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
paused_ = true;
|
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 =
|
auto threads =
|
||||||
kernel_state()->object_table()->GetObjectsByType<kernel::XThread>(
|
kernel_state()->object_table()->GetObjectsByType<kernel::XThread>(
|
||||||
kernel::XObject::kTypeThread);
|
kernel::XObject::kTypeThread);
|
||||||
|
@ -320,6 +323,8 @@ void Emulator::Resume() {
|
||||||
paused_ = false;
|
paused_ = false;
|
||||||
XELOGD("! EMULATOR RESUMED !");
|
XELOGD("! EMULATOR RESUMED !");
|
||||||
|
|
||||||
|
graphics_system_->Resume();
|
||||||
|
|
||||||
auto threads =
|
auto threads =
|
||||||
kernel_state()->object_table()->GetObjectsByType<kernel::XThread>(
|
kernel_state()->object_table()->GetObjectsByType<kernel::XThread>(
|
||||||
kernel::XObject::kTypeThread);
|
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
|
// It's important we don't hold the global lock here! XThreads need to step
|
||||||
// forward (possibly through guarded regions) without worry!
|
// forward (possibly through guarded regions) without worry!
|
||||||
|
graphics_system_->Save(&stream);
|
||||||
kernel_state_->Save(&stream);
|
kernel_state_->Save(&stream);
|
||||||
memory_->Save(&stream);
|
memory_->Save(&stream);
|
||||||
map->Close(stream.offset());
|
map->Close(stream.offset());
|
||||||
|
@ -376,6 +382,9 @@ bool Emulator::RestoreFromFile(const std::wstring& path) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!graphics_system_->Restore(&stream)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!kernel_state_->Restore(&stream)) {
|
if (!kernel_state_->Restore(&stream)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "xenia/base/byte_stream.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
#include "xenia/base/profiling.h"
|
#include "xenia/base/profiling.h"
|
||||||
|
@ -163,6 +164,59 @@ void CommandProcessor::WorkerThreadMain() {
|
||||||
ShutdownContext();
|
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; }
|
bool CommandProcessor::SetupContext() { return true; }
|
||||||
|
|
||||||
void CommandProcessor::ShutdownContext() { context_.reset(); }
|
void CommandProcessor::ShutdownContext() { context_.reset(); }
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
#include "xenia/ui/graphics_context.h"
|
#include "xenia/ui/graphics_context.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
||||||
|
class ByteStream;
|
||||||
|
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
class GraphicsSystem;
|
class GraphicsSystem;
|
||||||
|
@ -91,6 +94,13 @@ class CommandProcessor {
|
||||||
|
|
||||||
void ExecutePacket(uint32_t ptr, uint32_t count);
|
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:
|
protected:
|
||||||
class RingbufferReader;
|
class RingbufferReader;
|
||||||
|
|
||||||
|
@ -214,6 +224,9 @@ class CommandProcessor {
|
||||||
|
|
||||||
Shader* active_vertex_shader_ = nullptr;
|
Shader* active_vertex_shader_ = nullptr;
|
||||||
Shader* active_pixel_shader_ = nullptr;
|
Shader* active_pixel_shader_ = nullptr;
|
||||||
|
|
||||||
|
bool paused_ = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gpu
|
} // namespace gpu
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "xenia/gpu/graphics_system.h"
|
#include "xenia/gpu/graphics_system.h"
|
||||||
|
|
||||||
|
#include "xenia/base/byte_stream.h"
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
|
@ -246,5 +247,31 @@ void GraphicsSystem::BeginTracing() {
|
||||||
|
|
||||||
void GraphicsSystem::EndTracing() { command_processor_->EndTracing(); }
|
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 gpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -61,6 +61,13 @@ class GraphicsSystem {
|
||||||
void BeginTracing();
|
void BeginTracing();
|
||||||
void EndTracing();
|
void EndTracing();
|
||||||
|
|
||||||
|
bool is_paused() const { return paused_; }
|
||||||
|
void Pause();
|
||||||
|
void Resume();
|
||||||
|
|
||||||
|
bool Save(ByteStream* stream);
|
||||||
|
bool Restore(ByteStream* stream);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GraphicsSystem();
|
GraphicsSystem();
|
||||||
|
|
||||||
|
@ -90,6 +97,8 @@ class GraphicsSystem {
|
||||||
|
|
||||||
RegisterFile register_file_;
|
RegisterFile register_file_;
|
||||||
std::unique_ptr<CommandProcessor> command_processor_;
|
std::unique_ptr<CommandProcessor> command_processor_;
|
||||||
|
|
||||||
|
bool paused_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gpu
|
} // namespace gpu
|
||||||
|
|
Loading…
Reference in New Issue