Main window, empty GPU files.
This commit is contained in:
@@ -12,111 +12,26 @@
|
||||
#include <poly/poly.h>
|
||||
#include <xenia/emulator.h>
|
||||
#include <xenia/cpu/processor.h>
|
||||
#include <xenia/gpu/command_processor.h>
|
||||
#include <xenia/gpu/gpu-private.h>
|
||||
#include <xenia/gpu/graphics_driver.h>
|
||||
#include <xenia/gpu/register_file.h>
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::gpu;
|
||||
using namespace xe::gpu::xenos;
|
||||
GraphicsSystem::GraphicsSystem(Emulator* emulator)
|
||||
: emulator_(emulator),
|
||||
memory_(emulator->memory()),
|
||||
interrupt_callback_(0),
|
||||
interrupt_callback_data_(0) {}
|
||||
|
||||
|
||||
GraphicsSystem::GraphicsSystem(Emulator* emulator) :
|
||||
emulator_(emulator), memory_(emulator->memory()),
|
||||
running_(false), driver_(nullptr),
|
||||
command_processor_(nullptr),
|
||||
interrupt_callback_(0), interrupt_callback_data_(0),
|
||||
thread_wait_(nullptr) {
|
||||
// Create the run loop used for any windows/etc.
|
||||
// This must be done on the thread we create the driver.
|
||||
run_loop_ = xe_run_loop_create();
|
||||
thread_wait_ = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
}
|
||||
|
||||
GraphicsSystem::~GraphicsSystem() {
|
||||
CloseHandle(thread_wait_);
|
||||
}
|
||||
GraphicsSystem::~GraphicsSystem() {}
|
||||
|
||||
X_STATUS GraphicsSystem::Setup() {
|
||||
processor_ = emulator_->processor();
|
||||
|
||||
// Create worker.
|
||||
command_processor_ = new CommandProcessor(this, memory_);
|
||||
|
||||
// Let the processor know we want register access callbacks.
|
||||
emulator_->memory()->AddMappedRange(
|
||||
0x7FC80000,
|
||||
0xFFFF0000,
|
||||
0x0000FFFF,
|
||||
this,
|
||||
reinterpret_cast<MMIOReadCallback>(MMIOReadRegisterThunk),
|
||||
reinterpret_cast<MMIOWriteCallback>(MMIOWriteRegisterThunk));
|
||||
|
||||
// Create worker thread.
|
||||
// This will initialize the graphics system.
|
||||
// Init needs to happen there so that any thread-local stuff
|
||||
// is created on the right thread.
|
||||
running_ = true;
|
||||
thread_ = std::thread(std::bind(&GraphicsSystem::ThreadStart, this));
|
||||
WaitForSingleObject(thread_wait_, INFINITE);
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void GraphicsSystem::ThreadStart() {
|
||||
poly::threading::set_name("GraphicsSystemThread");
|
||||
xe::Profiler::ThreadEnter("GraphicsSystemThread");
|
||||
|
||||
xe_run_loop_ref run_loop = xe_run_loop_retain(run_loop_);
|
||||
|
||||
// Initialize driver and ringbuffer.
|
||||
Initialize();
|
||||
assert_not_null(driver_);
|
||||
SetEvent(thread_wait_);
|
||||
|
||||
// Main run loop.
|
||||
while (running_) {
|
||||
// Peek main run loop.
|
||||
{
|
||||
SCOPE_profile_cpu_i("gpu", "GraphicsSystemRunLoopPump");
|
||||
if (xe_run_loop_pump(run_loop)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!running_) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Pump worker.
|
||||
command_processor_->Pump();
|
||||
|
||||
if (!running_) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Pump graphics system.
|
||||
Pump();
|
||||
}
|
||||
running_ = false;
|
||||
|
||||
xe_run_loop_release(run_loop);
|
||||
|
||||
xe::Profiler::ThreadExit();
|
||||
}
|
||||
|
||||
void GraphicsSystem::Initialize() {
|
||||
}
|
||||
|
||||
void GraphicsSystem::Shutdown() {
|
||||
running_ = false;
|
||||
thread_.join();
|
||||
|
||||
delete command_processor_;
|
||||
|
||||
xe_run_loop_release(run_loop_);
|
||||
}
|
||||
void GraphicsSystem::Shutdown() {}
|
||||
|
||||
void GraphicsSystem::SetInterruptCallback(uint32_t callback,
|
||||
uint32_t user_data) {
|
||||
@@ -126,70 +41,15 @@ void GraphicsSystem::SetInterruptCallback(uint32_t callback,
|
||||
}
|
||||
|
||||
void GraphicsSystem::InitializeRingBuffer(uint32_t ptr, uint32_t page_count) {
|
||||
// TODO(benvanik): an event?
|
||||
while (!driver_) {
|
||||
Sleep(0);
|
||||
}
|
||||
assert_not_null(driver_);
|
||||
command_processor_->Initialize(driver_, ptr, page_count);
|
||||
//
|
||||
}
|
||||
|
||||
void GraphicsSystem::EnableReadPointerWriteBack(uint32_t ptr,
|
||||
uint32_t block_size) {
|
||||
command_processor_->EnableReadPointerWriteBack(ptr, block_size);
|
||||
//
|
||||
}
|
||||
|
||||
uint64_t GraphicsSystem::ReadRegister(uint64_t addr) {
|
||||
uint32_t r = addr & 0xFFFF;
|
||||
if (FLAGS_trace_ring_buffer) {
|
||||
XELOGGPU("ReadRegister(%.4X)", r);
|
||||
}
|
||||
|
||||
RegisterFile* regs = driver_->register_file();
|
||||
|
||||
switch (r) {
|
||||
case 0x6530: // ????
|
||||
return 1;
|
||||
case 0x6544: // ? vblank pending?
|
||||
return 1;
|
||||
case 0x6584: // ????
|
||||
return 1;
|
||||
}
|
||||
|
||||
assert_true(r >= 0 && r < RegisterFile::kRegisterCount);
|
||||
return regs->values[r].u32;
|
||||
}
|
||||
|
||||
void GraphicsSystem::WriteRegister(uint64_t addr, uint64_t value) {
|
||||
uint32_t r = addr & 0xFFFF;
|
||||
if (FLAGS_trace_ring_buffer) {
|
||||
XELOGGPU("WriteRegister(%.4X, %.8X)", r, value);
|
||||
}
|
||||
|
||||
RegisterFile* regs = driver_->register_file();
|
||||
|
||||
switch (r) {
|
||||
case 0x0714: // CP_RB_WPTR
|
||||
command_processor_->UpdateWritePointer((uint32_t)value);
|
||||
break;
|
||||
case 0x6110: // ? swap related?
|
||||
XELOGW("Unimplemented GPU register %.4X write: %.8X", r, value);
|
||||
return;
|
||||
default:
|
||||
XELOGW("Unknown GPU register %.4X write: %.8X", r, value);
|
||||
break;
|
||||
}
|
||||
|
||||
assert_true(r >= 0 && r < RegisterFile::kRegisterCount);
|
||||
regs->values[r].u32 = (uint32_t)value;
|
||||
}
|
||||
|
||||
void GraphicsSystem::MarkVblank() {
|
||||
command_processor_->increment_counter();
|
||||
}
|
||||
|
||||
void GraphicsSystem::DispatchInterruptCallback(
|
||||
uint32_t source, uint32_t cpu) {
|
||||
void GraphicsSystem::DispatchInterruptCallback(uint32_t source, uint32_t cpu) {
|
||||
// Pick a CPU, if needed. We're going to guess 2. Because.
|
||||
if (cpu == 0xFFFFFFFF) {
|
||||
cpu = 2;
|
||||
@@ -202,7 +62,10 @@ void GraphicsSystem::DispatchInterruptCallback(
|
||||
if (!interrupt_callback_) {
|
||||
return;
|
||||
}
|
||||
uint64_t args[] = { source, interrupt_callback_data_ };
|
||||
processor_->ExecuteInterrupt(
|
||||
cpu, interrupt_callback_, args, poly::countof(args));
|
||||
uint64_t args[] = {source, interrupt_callback_data_};
|
||||
processor_->ExecuteInterrupt(cpu, interrupt_callback_, args,
|
||||
poly::countof(args));
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
Reference in New Issue
Block a user