/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2013 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ #include "xenia/gpu/graphics_system.h" #include "xenia/base/logging.h" #include "xenia/base/math.h" #include "xenia/cpu/processor.h" #include "xenia/gpu/gpu_flags.h" #include "xenia/kernel/xthread.h" namespace xe { namespace gpu { namespace gl4 { std::unique_ptr Create(Emulator* emulator); } // namespace gl4 std::unique_ptr GraphicsSystem::Create(Emulator* emulator) { if (FLAGS_gpu.compare("gl4") == 0) { return xe::gpu::gl4::Create(emulator); } else { // Create best available. std::unique_ptr best; best = xe::gpu::gl4::Create(emulator); if (best) { return best; } // Nothing! return nullptr; } } GraphicsSystem::GraphicsSystem(Emulator* emulator) : emulator_(emulator) {} GraphicsSystem::~GraphicsSystem() = default; X_STATUS GraphicsSystem::Setup(cpu::Processor* processor, ui::Loop* target_loop, ui::Window* target_window) { processor_ = processor; memory_ = processor->memory(); target_loop_ = target_loop; target_window_ = target_window; return X_STATUS_SUCCESS; } void GraphicsSystem::Shutdown() {} void GraphicsSystem::SetInterruptCallback(uint32_t callback, uint32_t user_data) { interrupt_callback_ = callback; interrupt_callback_data_ = user_data; XELOGGPU("SetInterruptCallback(%.4X, %.4X)", callback, user_data); } void GraphicsSystem::DispatchInterruptCallback(uint32_t source, uint32_t cpu) { if (!interrupt_callback_) { return; } auto thread = kernel::XThread::GetCurrentThread(); assert_not_null(thread); // Pick a CPU, if needed. We're going to guess 2. Because. if (cpu == 0xFFFFFFFF) { cpu = 2; } thread->SetActiveCpu(cpu); // XELOGGPU("Dispatching GPU interrupt at %.8X w/ mode %d on cpu %d", // interrupt_callback_, source, cpu); uint64_t args[] = {source, interrupt_callback_data_}; processor_->ExecuteInterrupt(thread->thread_state(), interrupt_callback_, args, xe::countof(args)); } } // namespace gpu } // namespace xe