[Qt] Initial Qt window initialization
This commit is contained in:
parent
76fb04eaf3
commit
99d6788b2c
|
@ -10,6 +10,7 @@
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
|
||||||
#include "xenia/app/emulator_window.h"
|
#include "xenia/app/emulator_window.h"
|
||||||
|
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
|
||||||
|
|
||||||
#include "xenia/ui/vulkan/vulkan_instance.h"
|
#include "xenia/ui/vulkan/vulkan_instance.h"
|
||||||
#include "xenia/ui/vulkan/vulkan_provider.h"
|
#include "xenia/ui/vulkan/vulkan_provider.h"
|
||||||
|
@ -29,8 +30,28 @@ namespace app {
|
||||||
EmulatorWindow::EmulatorWindow() {}
|
EmulatorWindow::EmulatorWindow() {}
|
||||||
|
|
||||||
bool EmulatorWindow::Setup() {
|
bool EmulatorWindow::Setup() {
|
||||||
// TODO(DrChat): We own xe::Emulator. Create it and set it up.
|
// TODO(DrChat): Pass in command line arguments.
|
||||||
return false;
|
emulator_ = std::make_unique<xe::Emulator>(L"");
|
||||||
|
|
||||||
|
// Initialize the graphics backend.
|
||||||
|
// TODO(DrChat): Pick from gpu command line flag.
|
||||||
|
if (!InitializeVulkan()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto graphics_factory = [&](cpu::Processor* processor,
|
||||||
|
kernel::KernelState* kernel_state) {
|
||||||
|
auto graphics = std::make_unique<gpu::vulkan::VulkanGraphicsSystem>();
|
||||||
|
if (graphics->Setup(processor, kernel_state,
|
||||||
|
graphics_provider_->CreateOffscreenContext())) {
|
||||||
|
return std::unique_ptr<gpu::vulkan::VulkanGraphicsSystem>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return graphics;
|
||||||
|
};
|
||||||
|
|
||||||
|
X_STATUS result = emulator_->Setup(nullptr, graphics_factory, nullptr);
|
||||||
|
return result == X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatorWindow::InitializeVulkan() {
|
bool EmulatorWindow::InitializeVulkan() {
|
||||||
|
|
|
@ -38,7 +38,7 @@ class EmulatorWindow : public QMainWindow {
|
||||||
private:
|
private:
|
||||||
void CreateMenuBar();
|
void CreateMenuBar();
|
||||||
|
|
||||||
std::unique_ptr<xe::Emulator*> emulator_;
|
std::unique_ptr<xe::Emulator> emulator_;
|
||||||
|
|
||||||
std::unique_ptr<QWindow> graphics_window_;
|
std::unique_ptr<QWindow> graphics_window_;
|
||||||
std::unique_ptr<ui::GraphicsProvider> graphics_provider_;
|
std::unique_ptr<ui::GraphicsProvider> graphics_provider_;
|
||||||
|
|
|
@ -75,8 +75,10 @@ class Logger {
|
||||||
~Logger() {
|
~Logger() {
|
||||||
running_ = false;
|
running_ = false;
|
||||||
xe::threading::Wait(write_thread_.get(), true);
|
xe::threading::Wait(write_thread_.get(), true);
|
||||||
fflush(file_);
|
if (file_) {
|
||||||
fclose(file_);
|
fflush(file_);
|
||||||
|
fclose(file_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppendLine(uint32_t thread_id, LogLevel level, const char prefix_char,
|
void AppendLine(uint32_t thread_id, LogLevel level, const char prefix_char,
|
||||||
|
@ -92,8 +94,8 @@ class Logger {
|
||||||
line.prefix_char = prefix_char;
|
line.prefix_char = prefix_char;
|
||||||
|
|
||||||
// First, run a check and see if we can increment write
|
// First, run a check and see if we can increment write
|
||||||
// head without any problems. If so, cmpxchg it to reserve some space in the
|
// head without any problems. If so, cmpxchg it to reserve some space in
|
||||||
// ring. If someone beats us, loop around.
|
// the ring. If someone beats us, loop around.
|
||||||
//
|
//
|
||||||
// Once we have a reservation, write our data and then increment the write
|
// Once we have a reservation, write our data and then increment the write
|
||||||
// tail.
|
// tail.
|
||||||
|
@ -184,8 +186,8 @@ class Logger {
|
||||||
line.thread_id);
|
line.thread_id);
|
||||||
Write(prefix, sizeof(prefix) - 1);
|
Write(prefix, sizeof(prefix) - 1);
|
||||||
if (line.buffer_length) {
|
if (line.buffer_length) {
|
||||||
// Get access to the line data - which may be split in the ring buffer
|
// Get access to the line data - which may be split in the ring
|
||||||
// - and write it out in parts.
|
// buffer - and write it out in parts.
|
||||||
auto line_range = rb.BeginRead(line.buffer_length);
|
auto line_range = rb.BeginRead(line.buffer_length);
|
||||||
Write(reinterpret_cast<const char*>(line_range.first),
|
Write(reinterpret_cast<const char*>(line_range.first),
|
||||||
line_range.first_length);
|
line_range.first_length);
|
||||||
|
|
|
@ -105,8 +105,9 @@ bool DebugWindow::Initialize() {
|
||||||
window_->Resize(1500, 1000);
|
window_->Resize(1500, 1000);
|
||||||
|
|
||||||
// Create the graphics context used for drawing.
|
// Create the graphics context used for drawing.
|
||||||
auto provider = emulator_->display_window()->context()->provider();
|
// TODO(DrChat): Refactor this.
|
||||||
window_->set_context(provider->CreateContext(window_.get()));
|
// auto provider = emulator_->display_window()->context()->provider();
|
||||||
|
// window_->set_context(provider->CreateContext(window_.get()));
|
||||||
|
|
||||||
// Enable imgui input.
|
// Enable imgui input.
|
||||||
window_->set_imgui_input_enabled(true);
|
window_->set_imgui_input_enabled(true);
|
||||||
|
|
|
@ -77,17 +77,15 @@ Emulator::~Emulator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS Emulator::Setup(
|
X_STATUS Emulator::Setup(
|
||||||
ui::Window* display_window,
|
|
||||||
std::function<std::unique_ptr<apu::AudioSystem>(cpu::Processor*)>
|
std::function<std::unique_ptr<apu::AudioSystem>(cpu::Processor*)>
|
||||||
audio_system_factory,
|
audio_system_factory,
|
||||||
std::function<std::unique_ptr<gpu::GraphicsSystem>()>
|
std::function<std::unique_ptr<gpu::GraphicsSystem>(cpu::Processor*,
|
||||||
|
kernel::KernelState*)>
|
||||||
graphics_system_factory,
|
graphics_system_factory,
|
||||||
std::function<std::vector<std::unique_ptr<hid::InputDriver>>(ui::Window*)>
|
std::function<std::vector<std::unique_ptr<hid::InputDriver>>()>
|
||||||
input_driver_factory) {
|
input_driver_factory) {
|
||||||
X_STATUS result = X_STATUS_UNSUCCESSFUL;
|
X_STATUS result = X_STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
display_window_ = display_window;
|
|
||||||
|
|
||||||
// Initialize clock.
|
// Initialize clock.
|
||||||
// 360 uses a 50MHz clock.
|
// 360 uses a 50MHz clock.
|
||||||
Clock::set_guest_tick_frequency(50000000);
|
Clock::set_guest_tick_frequency(50000000);
|
||||||
|
@ -132,27 +130,34 @@ X_STATUS Emulator::Setup(
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bring up the virtual filesystem used by the kernel.
|
||||||
|
file_system_ = std::make_unique<xe::vfs::VirtualFileSystem>();
|
||||||
|
|
||||||
|
// Shared kernel state.
|
||||||
|
kernel_state_ = std::make_unique<xe::kernel::KernelState>(this);
|
||||||
|
|
||||||
// Initialize the APU.
|
// Initialize the APU.
|
||||||
if (audio_system_factory) {
|
if (audio_system_factory) {
|
||||||
audio_system_ = audio_system_factory(processor_.get());
|
audio_system_ = audio_system_factory(processor_.get());
|
||||||
if (!audio_system_) {
|
if (!audio_system_) {
|
||||||
return X_STATUS_NOT_IMPLEMENTED;
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the GPU.
|
// Initialize the GPU.
|
||||||
graphics_system_ = graphics_system_factory();
|
graphics_system_ =
|
||||||
|
graphics_system_factory(processor_.get(), kernel_state_.get());
|
||||||
if (!graphics_system_) {
|
if (!graphics_system_) {
|
||||||
return X_STATUS_NOT_IMPLEMENTED;
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the HID.
|
// Initialize all HID drivers.
|
||||||
input_system_ = std::make_unique<xe::hid::InputSystem>(display_window_);
|
input_system_ = std::make_unique<xe::hid::InputSystem>();
|
||||||
if (!input_system_) {
|
if (!input_system_) {
|
||||||
return X_STATUS_NOT_IMPLEMENTED;
|
return X_STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
if (input_driver_factory) {
|
if (input_driver_factory) {
|
||||||
auto input_drivers = input_driver_factory(display_window_);
|
auto input_drivers = input_driver_factory();
|
||||||
for (size_t i = 0; i < input_drivers.size(); ++i) {
|
for (size_t i = 0; i < input_drivers.size(); ++i) {
|
||||||
input_system_->AddDriver(std::move(input_drivers[i]));
|
input_system_->AddDriver(std::move(input_drivers[i]));
|
||||||
}
|
}
|
||||||
|
@ -163,26 +168,6 @@ X_STATUS Emulator::Setup(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bring up the virtual filesystem used by the kernel.
|
|
||||||
file_system_ = std::make_unique<xe::vfs::VirtualFileSystem>();
|
|
||||||
|
|
||||||
// Shared kernel state.
|
|
||||||
kernel_state_ = std::make_unique<xe::kernel::KernelState>(this);
|
|
||||||
|
|
||||||
// Setup the core components.
|
|
||||||
result = graphics_system_->Setup(processor_.get(), kernel_state_.get(),
|
|
||||||
display_window_);
|
|
||||||
if (result) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (audio_system_) {
|
|
||||||
result = audio_system_->Setup(kernel_state_.get());
|
|
||||||
if (result) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HLE kernel modules.
|
// HLE kernel modules.
|
||||||
kernel_state_->LoadKernelModule<kernel::xboxkrnl::XboxkrnlModule>();
|
kernel_state_->LoadKernelModule<kernel::xboxkrnl::XboxkrnlModule>();
|
||||||
kernel_state_->LoadKernelModule<kernel::xam::XamModule>();
|
kernel_state_->LoadKernelModule<kernel::xam::XamModule>();
|
||||||
|
@ -191,14 +176,6 @@ X_STATUS Emulator::Setup(
|
||||||
// Initialize emulator fallback exception handling last.
|
// Initialize emulator fallback exception handling last.
|
||||||
ExceptionHandler::Install(Emulator::ExceptionCallbackThunk, this);
|
ExceptionHandler::Install(Emulator::ExceptionCallbackThunk, this);
|
||||||
|
|
||||||
if (display_window_) {
|
|
||||||
// Finish initializing the display.
|
|
||||||
display_window_->loop()->PostSynchronous([this]() {
|
|
||||||
xe::ui::GraphicsContextLock context_lock(display_window_->context());
|
|
||||||
Profiler::set_window(display_window_);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,16 +513,6 @@ bool Emulator::ExceptionCallback(Exception* ex) {
|
||||||
context->v[i].i32[1], context->v[i].i32[2], context->v[i].i32[3]);
|
context->v[i].i32[1], context->v[i].i32[2], context->v[i].i32[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display a dialog telling the user the guest has crashed.
|
|
||||||
display_window()->loop()->PostSynchronous([&]() {
|
|
||||||
xe::ui::ImGuiDialog::ShowMessageBox(
|
|
||||||
display_window(), "Uh-oh!",
|
|
||||||
"The guest has crashed.\n\n"
|
|
||||||
""
|
|
||||||
"Xenia has now paused itself.\n"
|
|
||||||
"A crash dump has been written into the log.");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Now suspend ourself (we should be a guest thread).
|
// Now suspend ourself (we should be a guest thread).
|
||||||
current_thread->Suspend(nullptr);
|
current_thread->Suspend(nullptr);
|
||||||
|
|
||||||
|
@ -635,7 +602,7 @@ X_STATUS Emulator::CompleteLaunch(const std::wstring& path,
|
||||||
game_title_ = xe::to_wstring(db.title());
|
game_title_ = xe::to_wstring(db.title());
|
||||||
auto icon_block = db.icon();
|
auto icon_block = db.icon();
|
||||||
if (icon_block) {
|
if (icon_block) {
|
||||||
display_window_->SetIcon(icon_block.buffer, icon_block.size);
|
// display_window_->SetIcon(icon_block.buffer, icon_block.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,9 +62,6 @@ class Emulator {
|
||||||
// Are we currently running a title?
|
// Are we currently running a title?
|
||||||
bool is_title_open() const { return title_id_ != 0; }
|
bool is_title_open() const { return title_id_ != 0; }
|
||||||
|
|
||||||
// Window used for displaying graphical output.
|
|
||||||
ui::Window* display_window() const { return display_window_; }
|
|
||||||
|
|
||||||
// Guest memory system modelling the RAM (both virtual and physical) of the
|
// Guest memory system modelling the RAM (both virtual and physical) of the
|
||||||
// system.
|
// system.
|
||||||
Memory* memory() const { return memory_.get(); }
|
Memory* memory() const { return memory_.get(); }
|
||||||
|
@ -101,12 +98,12 @@ class Emulator {
|
||||||
// Once this function returns a game can be launched using one of the Launch
|
// Once this function returns a game can be launched using one of the Launch
|
||||||
// functions.
|
// functions.
|
||||||
X_STATUS Setup(
|
X_STATUS Setup(
|
||||||
ui::Window* display_window,
|
|
||||||
std::function<std::unique_ptr<apu::AudioSystem>(cpu::Processor*)>
|
std::function<std::unique_ptr<apu::AudioSystem>(cpu::Processor*)>
|
||||||
audio_system_factory,
|
audio_system_factory,
|
||||||
std::function<std::unique_ptr<gpu::GraphicsSystem>()>
|
std::function<std::unique_ptr<gpu::GraphicsSystem>(cpu::Processor*,
|
||||||
|
kernel::KernelState*)>
|
||||||
graphics_system_factory,
|
graphics_system_factory,
|
||||||
std::function<std::vector<std::unique_ptr<hid::InputDriver>>(ui::Window*)>
|
std::function<std::vector<std::unique_ptr<hid::InputDriver>>()>
|
||||||
input_driver_factory);
|
input_driver_factory);
|
||||||
|
|
||||||
// Terminates the currently running title.
|
// Terminates the currently running title.
|
||||||
|
@ -156,8 +153,6 @@ class Emulator {
|
||||||
std::wstring command_line_;
|
std::wstring command_line_;
|
||||||
std::wstring game_title_;
|
std::wstring game_title_;
|
||||||
|
|
||||||
ui::Window* display_window_;
|
|
||||||
|
|
||||||
std::unique_ptr<Memory> memory_;
|
std::unique_ptr<Memory> memory_;
|
||||||
|
|
||||||
std::unique_ptr<cpu::Processor> processor_;
|
std::unique_ptr<cpu::Processor> processor_;
|
||||||
|
|
|
@ -46,7 +46,7 @@ CommandProcessor::CommandProcessor(GraphicsSystem* graphics_system,
|
||||||
CommandProcessor::~CommandProcessor() = default;
|
CommandProcessor::~CommandProcessor() = default;
|
||||||
|
|
||||||
bool CommandProcessor::Initialize(
|
bool CommandProcessor::Initialize(
|
||||||
std::unique_ptr<xe::ui::GraphicsContext> context) {
|
std::unique_ptr<ui::GraphicsContext> context) {
|
||||||
context_ = std::move(context);
|
context_ = std::move(context);
|
||||||
|
|
||||||
worker_running_ = true;
|
worker_running_ = true;
|
||||||
|
@ -231,7 +231,7 @@ bool CommandProcessor::Restore(ByteStream* stream) {
|
||||||
|
|
||||||
bool CommandProcessor::SetupContext() { return true; }
|
bool CommandProcessor::SetupContext() { return true; }
|
||||||
|
|
||||||
void CommandProcessor::ShutdownContext() { context_.reset(); }
|
void CommandProcessor::ShutdownContext() {}
|
||||||
|
|
||||||
void CommandProcessor::InitializeRingBuffer(uint32_t ptr, uint32_t log2_size) {
|
void CommandProcessor::InitializeRingBuffer(uint32_t ptr, uint32_t log2_size) {
|
||||||
read_ptr_index_ = 0;
|
read_ptr_index_ = 0;
|
||||||
|
|
|
@ -114,7 +114,7 @@ class CommandProcessor {
|
||||||
Shader* active_vertex_shader() const { return active_vertex_shader_; }
|
Shader* active_vertex_shader() const { return active_vertex_shader_; }
|
||||||
Shader* active_pixel_shader() const { return active_pixel_shader_; }
|
Shader* active_pixel_shader() const { return active_pixel_shader_; }
|
||||||
|
|
||||||
virtual bool Initialize(std::unique_ptr<xe::ui::GraphicsContext> context);
|
virtual bool Initialize(std::unique_ptr<ui::GraphicsContext> context);
|
||||||
virtual void Shutdown();
|
virtual void Shutdown();
|
||||||
|
|
||||||
void CallInThread(std::function<void()> fn);
|
void CallInThread(std::function<void()> fn);
|
||||||
|
@ -255,7 +255,7 @@ class CommandProcessor {
|
||||||
std::atomic<bool> worker_running_;
|
std::atomic<bool> worker_running_;
|
||||||
kernel::object_ref<kernel::XHostThread> worker_thread_;
|
kernel::object_ref<kernel::XHostThread> worker_thread_;
|
||||||
|
|
||||||
std::unique_ptr<xe::ui::GraphicsContext> context_;
|
std::unique_ptr<ui::GraphicsContext> context_;
|
||||||
SwapMode swap_mode_ = SwapMode::kNormal;
|
SwapMode swap_mode_ = SwapMode::kNormal;
|
||||||
SwapState swap_state_;
|
SwapState swap_state_;
|
||||||
std::function<void()> swap_request_handler_;
|
std::function<void()> swap_request_handler_;
|
||||||
|
|
|
@ -39,69 +39,22 @@ GraphicsSystem::GraphicsSystem() : vsync_worker_running_(false) {}
|
||||||
|
|
||||||
GraphicsSystem::~GraphicsSystem() = default;
|
GraphicsSystem::~GraphicsSystem() = default;
|
||||||
|
|
||||||
X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
|
X_STATUS GraphicsSystem::Setup(
|
||||||
kernel::KernelState* kernel_state,
|
cpu::Processor* processor, kernel::KernelState* kernel_state,
|
||||||
ui::Window* target_window) {
|
std::unique_ptr<ui::GraphicsContext> graphics_context) {
|
||||||
memory_ = processor->memory();
|
memory_ = processor->memory();
|
||||||
processor_ = processor;
|
processor_ = processor;
|
||||||
kernel_state_ = kernel_state;
|
kernel_state_ = kernel_state;
|
||||||
target_window_ = target_window;
|
|
||||||
|
|
||||||
// Initialize display and rendering context.
|
|
||||||
// This must happen on the UI thread.
|
|
||||||
std::unique_ptr<xe::ui::GraphicsContext> processor_context = nullptr;
|
|
||||||
if (provider_) {
|
|
||||||
if (target_window_) {
|
|
||||||
target_window_->loop()->PostSynchronous([&]() {
|
|
||||||
// Create the context used for presentation.
|
|
||||||
assert_null(target_window->context());
|
|
||||||
target_window_->set_context(provider_->CreateContext(target_window_));
|
|
||||||
|
|
||||||
// Setup the context the command processor will do all its drawing in.
|
|
||||||
// It's shared with the display context so that we can resolve
|
|
||||||
// framebuffers from it.
|
|
||||||
processor_context = provider()->CreateOffscreenContext();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
processor_context = provider()->CreateOffscreenContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!processor_context) {
|
|
||||||
xe::FatalError(
|
|
||||||
"Unable to initialize graphics context. Xenia requires Vulkan "
|
|
||||||
"support.\n"
|
|
||||||
"\n"
|
|
||||||
"Ensure you have the latest drivers for your GPU and "
|
|
||||||
"that it supports Vulkan.\n"
|
|
||||||
"\n"
|
|
||||||
"See http://xenia.jp/faq/ for more information and a list of "
|
|
||||||
"supported GPUs.");
|
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create command processor. This will spin up a thread to process all
|
// Create command processor. This will spin up a thread to process all
|
||||||
// incoming ringbuffer packets.
|
// incoming ringbuffer packets.
|
||||||
command_processor_ = CreateCommandProcessor();
|
command_processor_ = CreateCommandProcessor();
|
||||||
if (!command_processor_->Initialize(std::move(processor_context))) {
|
if (!command_processor_->Initialize(std::move(graphics_context))) {
|
||||||
XELOGE("Unable to initialize command processor");
|
XELOGE("Unable to initialize command processor");
|
||||||
return X_STATUS_UNSUCCESSFUL;
|
return X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_window) {
|
command_processor_->set_swap_request_handler([]() {});
|
||||||
command_processor_->set_swap_request_handler(
|
|
||||||
[this]() { target_window_->Invalidate(); });
|
|
||||||
|
|
||||||
// Watch for paint requests to do our swap.
|
|
||||||
target_window->on_painting.AddListener(
|
|
||||||
[this](xe::ui::UIEvent* e) { Swap(e); });
|
|
||||||
|
|
||||||
// Watch for context lost events.
|
|
||||||
target_window->on_context_lost.AddListener(
|
|
||||||
[this](xe::ui::UIEvent* e) { Reset(); });
|
|
||||||
} else {
|
|
||||||
command_processor_->set_swap_request_handler([]() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let the processor know we want register access callbacks.
|
// Let the processor know we want register access callbacks.
|
||||||
memory_->AddVirtualMappedRange(
|
memory_->AddVirtualMappedRange(
|
||||||
|
|
|
@ -43,7 +43,7 @@ class GraphicsSystem {
|
||||||
|
|
||||||
virtual X_STATUS Setup(cpu::Processor* processor,
|
virtual X_STATUS Setup(cpu::Processor* processor,
|
||||||
kernel::KernelState* kernel_state,
|
kernel::KernelState* kernel_state,
|
||||||
ui::Window* target_window);
|
std::unique_ptr<ui::GraphicsContext> graphics_context);
|
||||||
virtual void Shutdown();
|
virtual void Shutdown();
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
|
|
||||||
|
@ -91,7 +91,6 @@ class GraphicsSystem {
|
||||||
Memory* memory_ = nullptr;
|
Memory* memory_ = nullptr;
|
||||||
cpu::Processor* processor_ = nullptr;
|
cpu::Processor* processor_ = nullptr;
|
||||||
kernel::KernelState* kernel_state_ = nullptr;
|
kernel::KernelState* kernel_state_ = nullptr;
|
||||||
ui::Window* target_window_ = nullptr;
|
|
||||||
std::unique_ptr<ui::GraphicsProvider> provider_;
|
std::unique_ptr<ui::GraphicsProvider> provider_;
|
||||||
|
|
||||||
uint32_t interrupt_callback_ = 0;
|
uint32_t interrupt_callback_ = 0;
|
||||||
|
|
|
@ -21,14 +21,10 @@ NullGraphicsSystem::NullGraphicsSystem() {}
|
||||||
|
|
||||||
NullGraphicsSystem::~NullGraphicsSystem() {}
|
NullGraphicsSystem::~NullGraphicsSystem() {}
|
||||||
|
|
||||||
X_STATUS NullGraphicsSystem::Setup(cpu::Processor* processor,
|
X_STATUS NullGraphicsSystem::Setup(
|
||||||
kernel::KernelState* kernel_state,
|
cpu::Processor* processor, kernel::KernelState* kernel_state,
|
||||||
ui::Window* target_window) {
|
std::unique_ptr<ui::GraphicsContext> context) {
|
||||||
// This is a null graphics system, but we still setup vulkan because UI needs
|
return GraphicsSystem::Setup(processor, kernel_state, std::move(context));
|
||||||
// it through us :|
|
|
||||||
provider_ = xe::ui::vulkan::VulkanProvider::Create(target_window);
|
|
||||||
|
|
||||||
return GraphicsSystem::Setup(processor, kernel_state, target_window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NullGraphicsSystem::Shutdown() { GraphicsSystem::Shutdown(); }
|
void NullGraphicsSystem::Shutdown() { GraphicsSystem::Shutdown(); }
|
||||||
|
|
|
@ -27,7 +27,7 @@ class NullGraphicsSystem : public GraphicsSystem {
|
||||||
std::wstring name() const override { return L"null"; }
|
std::wstring name() const override { return L"null"; }
|
||||||
|
|
||||||
X_STATUS Setup(cpu::Processor* processor, kernel::KernelState* kernel_state,
|
X_STATUS Setup(cpu::Processor* processor, kernel::KernelState* kernel_state,
|
||||||
ui::Window* target_window) override;
|
std::unique_ptr<ui::GraphicsContext> context) override;
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -104,8 +104,12 @@ int TraceDump::Main(const std::vector<std::wstring>& args) {
|
||||||
bool TraceDump::Setup() {
|
bool TraceDump::Setup() {
|
||||||
// Create the emulator but don't initialize so we can setup the window.
|
// Create the emulator but don't initialize so we can setup the window.
|
||||||
emulator_ = std::make_unique<Emulator>(L"");
|
emulator_ = std::make_unique<Emulator>(L"");
|
||||||
X_STATUS result = emulator_->Setup(
|
X_STATUS result =
|
||||||
nullptr, nullptr, [this]() { return CreateGraphicsSystem(); }, nullptr);
|
emulator_->Setup(nullptr,
|
||||||
|
[this](cpu::Processor*, kernel::KernelState*) {
|
||||||
|
return CreateGraphicsSystem();
|
||||||
|
},
|
||||||
|
nullptr);
|
||||||
if (XFAILED(result)) {
|
if (XFAILED(result)) {
|
||||||
XELOGE("Failed to setup emulator: %.8X", result);
|
XELOGE("Failed to setup emulator: %.8X", result);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -124,8 +124,11 @@ bool TraceViewer::Setup() {
|
||||||
// Create the emulator but don't initialize so we can setup the window.
|
// Create the emulator but don't initialize so we can setup the window.
|
||||||
emulator_ = std::make_unique<Emulator>(L"");
|
emulator_ = std::make_unique<Emulator>(L"");
|
||||||
X_STATUS result =
|
X_STATUS result =
|
||||||
emulator_->Setup(window_.get(), nullptr,
|
emulator_->Setup(nullptr,
|
||||||
[this]() { return CreateGraphicsSystem(); }, nullptr);
|
[this](cpu::Processor*, kernel::KernelState*) {
|
||||||
|
return CreateGraphicsSystem();
|
||||||
|
},
|
||||||
|
nullptr);
|
||||||
if (XFAILED(result)) {
|
if (XFAILED(result)) {
|
||||||
XELOGE("Failed to setup emulator: %.8X", result);
|
XELOGE("Failed to setup emulator: %.8X", result);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -60,7 +60,7 @@ bool VulkanCommandProcessor::SetupContext() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Acquire our device and queue.
|
// Acquire our device and queue.
|
||||||
auto context = static_cast<xe::ui::vulkan::VulkanContext*>(context_.get());
|
auto context = static_cast<ui::vulkan::VulkanContext*>(context_.get());
|
||||||
device_ = context->device();
|
device_ = context->device();
|
||||||
queue_ = device_->AcquireQueue(device_->queue_family_index());
|
queue_ = device_->AcquireQueue(device_->queue_family_index());
|
||||||
if (!queue_) {
|
if (!queue_) {
|
||||||
|
|
|
@ -33,24 +33,17 @@ using xe::ui::vulkan::CheckResult;
|
||||||
VulkanGraphicsSystem::VulkanGraphicsSystem() {}
|
VulkanGraphicsSystem::VulkanGraphicsSystem() {}
|
||||||
VulkanGraphicsSystem::~VulkanGraphicsSystem() = default;
|
VulkanGraphicsSystem::~VulkanGraphicsSystem() = default;
|
||||||
|
|
||||||
X_STATUS VulkanGraphicsSystem::Setup(cpu::Processor* processor,
|
X_STATUS VulkanGraphicsSystem::Setup(
|
||||||
kernel::KernelState* kernel_state,
|
cpu::Processor* processor, kernel::KernelState* kernel_state,
|
||||||
ui::Window* target_window) {
|
std::unique_ptr<ui::GraphicsContext> context) {
|
||||||
// Must create the provider so we can create contexts.
|
device_ = static_cast<ui::vulkan::VulkanContext*>(context.get())->device();
|
||||||
auto provider = xe::ui::vulkan::VulkanProvider::Create(target_window);
|
|
||||||
device_ = provider->device();
|
|
||||||
provider_ = std::move(provider);
|
|
||||||
|
|
||||||
auto result = GraphicsSystem::Setup(processor, kernel_state, target_window);
|
auto result =
|
||||||
|
GraphicsSystem::Setup(processor, kernel_state, std::move(context));
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_window) {
|
|
||||||
display_context_ = reinterpret_cast<xe::ui::vulkan::VulkanContext*>(
|
|
||||||
target_window->context());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create our own command pool we can use for captures.
|
// Create our own command pool we can use for captures.
|
||||||
VkCommandPoolCreateInfo create_info = {
|
VkCommandPoolCreateInfo create_info = {
|
||||||
VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||||
|
|
|
@ -27,7 +27,7 @@ class VulkanGraphicsSystem : public GraphicsSystem {
|
||||||
std::wstring name() const override { return L"Vulkan"; }
|
std::wstring name() const override { return L"Vulkan"; }
|
||||||
|
|
||||||
X_STATUS Setup(cpu::Processor* processor, kernel::KernelState* kernel_state,
|
X_STATUS Setup(cpu::Processor* processor, kernel::KernelState* kernel_state,
|
||||||
ui::Window* target_window) override;
|
std::unique_ptr<ui::GraphicsContext> context) override;
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
|
|
||||||
std::unique_ptr<xe::ui::RawImage> Capture() override;
|
std::unique_ptr<xe::ui::RawImage> Capture() override;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace hid {
|
namespace hid {
|
||||||
|
|
||||||
InputSystem::InputSystem(xe::ui::Window* window) : window_(window) {}
|
InputSystem::InputSystem() {}
|
||||||
|
|
||||||
InputSystem::~InputSystem() = default;
|
InputSystem::~InputSystem() = default;
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,9 @@ namespace hid {
|
||||||
|
|
||||||
class InputSystem {
|
class InputSystem {
|
||||||
public:
|
public:
|
||||||
explicit InputSystem(xe::ui::Window* window);
|
explicit InputSystem();
|
||||||
~InputSystem();
|
~InputSystem();
|
||||||
|
|
||||||
xe::ui::Window* window() const { return window_; }
|
|
||||||
|
|
||||||
X_STATUS Setup();
|
X_STATUS Setup();
|
||||||
|
|
||||||
void AddDriver(std::unique_ptr<InputDriver> driver);
|
void AddDriver(std::unique_ptr<InputDriver> driver);
|
||||||
|
@ -45,8 +43,6 @@ class InputSystem {
|
||||||
X_INPUT_KEYSTROKE* out_keystroke);
|
X_INPUT_KEYSTROKE* out_keystroke);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
xe::ui::Window* window_ = nullptr;
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<InputDriver>> drivers_;
|
std::vector<std::unique_ptr<InputDriver>> drivers_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,7 @@ SHIM_CALL XamShowMessageBoxUI_shim(PPCContext* ppc_context,
|
||||||
// Auto-pick the focused button.
|
// Auto-pick the focused button.
|
||||||
chosen_button = active_button;
|
chosen_button = active_button;
|
||||||
} else {
|
} else {
|
||||||
|
/*
|
||||||
auto display_window = kernel_state->emulator()->display_window();
|
auto display_window = kernel_state->emulator()->display_window();
|
||||||
xe::threading::Fence fence;
|
xe::threading::Fence fence;
|
||||||
display_window->loop()->PostSynchronous([&]() {
|
display_window->loop()->PostSynchronous([&]() {
|
||||||
|
@ -155,6 +156,7 @@ SHIM_CALL XamShowMessageBoxUI_shim(PPCContext* ppc_context,
|
||||||
++xam_dialogs_shown_;
|
++xam_dialogs_shown_;
|
||||||
fence.Wait();
|
fence.Wait();
|
||||||
--xam_dialogs_shown_;
|
--xam_dialogs_shown_;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
SHIM_SET_MEM_32(result_ptr, chosen_button);
|
SHIM_SET_MEM_32(result_ptr, chosen_button);
|
||||||
|
|
||||||
|
@ -258,6 +260,7 @@ dword_result_t XamShowKeyboardUI(dword_t user_index, dword_t flags,
|
||||||
|
|
||||||
std::wstring out_text;
|
std::wstring out_text;
|
||||||
|
|
||||||
|
/*
|
||||||
auto display_window = kernel_state()->emulator()->display_window();
|
auto display_window = kernel_state()->emulator()->display_window();
|
||||||
xe::threading::Fence fence;
|
xe::threading::Fence fence;
|
||||||
display_window->loop()->PostSynchronous([&]() {
|
display_window->loop()->PostSynchronous([&]() {
|
||||||
|
@ -270,6 +273,7 @@ dword_result_t XamShowKeyboardUI(dword_t user_index, dword_t flags,
|
||||||
++xam_dialogs_shown_;
|
++xam_dialogs_shown_;
|
||||||
fence.Wait();
|
fence.Wait();
|
||||||
--xam_dialogs_shown_;
|
--xam_dialogs_shown_;
|
||||||
|
*/
|
||||||
|
|
||||||
// Zero the output buffer.
|
// Zero the output buffer.
|
||||||
std::memset(buffer, 0, buffer_length * 2);
|
std::memset(buffer, 0, buffer_length * 2);
|
||||||
|
@ -330,6 +334,7 @@ SHIM_CALL XamShowDirtyDiscErrorUI_shim(PPCContext* ppc_context,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
auto display_window = kernel_state->emulator()->display_window();
|
auto display_window = kernel_state->emulator()->display_window();
|
||||||
xe::threading::Fence fence;
|
xe::threading::Fence fence;
|
||||||
display_window->loop()->PostSynchronous([&]() {
|
display_window->loop()->PostSynchronous([&]() {
|
||||||
|
@ -342,6 +347,7 @@ SHIM_CALL XamShowDirtyDiscErrorUI_shim(PPCContext* ppc_context,
|
||||||
++xam_dialogs_shown_;
|
++xam_dialogs_shown_;
|
||||||
fence.Wait();
|
fence.Wait();
|
||||||
--xam_dialogs_shown_;
|
--xam_dialogs_shown_;
|
||||||
|
*/
|
||||||
|
|
||||||
// This is death, and should never return.
|
// This is death, and should never return.
|
||||||
// TODO(benvanik): cleaner exit.
|
// TODO(benvanik): cleaner exit.
|
||||||
|
|
Loading…
Reference in New Issue