Wiring up register read/write from JIT -> GPU.

This commit is contained in:
Ben Vanik 2013-05-31 21:22:00 -07:00
parent edf3a9155b
commit ef0032ecff
14 changed files with 164 additions and 12 deletions

View File

@ -30,6 +30,8 @@ public:
}
virtual int Setup() = 0;
virtual void SetupGpuPointers(void* gpu_this,
void* gpu_read, void* gpu_write) = 0;
virtual int InitModule(ExecModule* module) = 0;
virtual int UninitModule(ExecModule* module) = 0;

View File

@ -11,6 +11,7 @@
#include <xenia/cpu/jit.h>
#include <xenia/cpu/ppc/disasm.h>
#include <xenia/gpu/graphics_system.h>
using namespace xe;
@ -66,6 +67,7 @@ Processor::~Processor() {
delete jit_;
delete sym_table_;
graphics_system_.reset();
export_resolver_.reset();
backend_.reset();
xe_memory_release(memory_);
@ -75,6 +77,15 @@ xe_memory_ref Processor::memory() {
return xe_memory_retain(memory_);
}
shared_ptr<gpu::GraphicsSystem> Processor::graphics_system() {
return graphics_system_;
}
void Processor::set_graphics_system(
shared_ptr<gpu::GraphicsSystem> graphics_system) {
graphics_system_ = graphics_system;
}
shared_ptr<ExportResolver> Processor::export_resolver() {
return export_resolver_;
}
@ -95,6 +106,12 @@ int Processor::Setup() {
return 1;
}
XEASSERTNOTNULL(graphics_system_.get());
jit_->SetupGpuPointers(
graphics_system_.get(),
(void*)&xe::gpu::GraphicsSystem::ReadRegisterThunk,
(void*)&xe::gpu::GraphicsSystem::WriteRegisterThunk);
return 0;
}
@ -235,7 +252,7 @@ FunctionSymbol* Processor::GetFunction(uint32_t address) {
return fn_symbol;
}
}
// Not found at all? That seems wrong...
XEASSERTALWAYS();
return NULL;

View File

@ -22,6 +22,13 @@
#include <xenia/kernel/xex2.h>
namespace xe {
namespace gpu {
class GraphicsSystem;
} // namespace gpu
} // namespace xe
namespace xe {
namespace cpu {
@ -34,6 +41,8 @@ public:
~Processor();
xe_memory_ref memory();
shared_ptr<gpu::GraphicsSystem> graphics_system();
void set_graphics_system(shared_ptr<gpu::GraphicsSystem> graphics_system);
shared_ptr<kernel::ExportResolver> export_resolver();
void set_export_resolver(shared_ptr<kernel::ExportResolver> export_resolver);
@ -54,7 +63,8 @@ public:
private:
xe_memory_ref memory_;
shared_ptr<Backend> backend_;
shared_ptr<kernel::ExportResolver> export_resolver_;
shared_ptr<gpu::GraphicsSystem> graphics_system_;
shared_ptr<kernel::ExportResolver> export_resolver_;
sdb::SymbolTable* sym_table_;
JIT* jit_;

View File

@ -10,6 +10,7 @@
#include <xenia/cpu/x64/x64_emit.h>
#include <xenia/cpu/cpu-private.h>
#include <xenia/gpu/graphics_system.h>
using namespace xe::cpu;
@ -449,9 +450,20 @@ XEEMITTER(lwz, 0x80000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// EA <- b + EXTS(D)
// RT <- i32.0 || MEM(EA, 4)
// Special GPU access (0x7FC8xxxx).
uint64_t constant_ea;
if (i.D.RA && e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
if ((constant_ea & 0xFFFF0000) == 0x7FC80000) {
GpVar reg(e.read_gpu_register((uint32_t)constant_ea));
e.update_gpr_value(i.D.RT, reg);
e.clear_constant_gpr_value(i.D.RT);
return 0;
}
}
GpVar ea(c.newGpVar());
if (i.D.RA) {
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));
@ -808,9 +820,18 @@ XEEMITTER(stw, 0x90000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
// EA <- b + EXTS(D)
// MEM(EA, 4) <- (RS)[32:63]
// Special GPU access (0x7FC8xxxx).
uint64_t constant_ea;
if (i.D.RA && e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
if ((constant_ea & 0xFFFF0000) == 0x7FC80000) {
e.write_gpu_register((uint32_t)constant_ea, e.gpr_value(i.D.RT));
return 0;
}
}
GpVar ea(c.newGpVar());
if (i.D.RA) {
uint64_t constant_ea;
if (e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
constant_ea += XEEXTS16(i.D.DS);
c.mov(ea, imm(constant_ea & 0xFFFFFFFF));

View File

@ -89,6 +89,13 @@ X64Emitter::~X64Emitter() {
lock_ = NULL;
}
void X64Emitter::SetupGpuPointers(void* gpu_this,
void* gpu_read, void* gpu_write) {
gpu_this_ = gpu_this;
gpu_read_ = gpu_read;
gpu_write_ = gpu_write;
}
void X64Emitter::Lock() {
xe_mutex_lock(lock_);
}
@ -1004,6 +1011,41 @@ int X64Emitter::GenerateIndirectionBranch(uint32_t cia, GpVar& target,
return 0;
}
GpVar X64Emitter::read_gpu_register(uint32_t r) {
X86Compiler& c = compiler_;
GpVar this_imm(c.newGpVar());
c.mov(this_imm, imm((uint64_t)gpu_this_));
GpVar reg_imm(c.newGpVar());
c.mov(reg_imm, imm(r & 0xFFFF));
X86CompilerFuncCall* call = c.call(gpu_read_);
call->setPrototype(kX86FuncConvDefault,
FuncBuilder2<uint64_t, void*, uint32_t>());
call->setArgument(0, this_imm);
call->setArgument(1, reg_imm);
GpVar res(c.newGpVar());
call->setReturn(res);
return res;
}
void X64Emitter::write_gpu_register(uint32_t r, GpVar& v) {
X86Compiler& c = compiler_;
GpVar this_imm(c.newGpVar());
c.mov(this_imm, imm((uint64_t)gpu_this_));
GpVar reg_imm(c.newGpVar());
c.mov(reg_imm, imm(r & 0xFFFF));
X86CompilerFuncCall* call = c.call(gpu_write_);
call->setPrototype(kX86FuncConvDefault,
FuncBuilder3<void, void*, uint32_t, uint64_t>());
call->setArgument(0, this_imm);
call->setArgument(1, reg_imm);
call->setArgument(2, v);
}
void X64Emitter::SetupLocals() {
X86Compiler& c = compiler_;

View File

@ -31,6 +31,8 @@ public:
X64Emitter(xe_memory_ref memory);
~X64Emitter();
void SetupGpuPointers(void* gpu_this, void* gpu_read, void* gpu_write);
void Lock();
void Unlock();
@ -55,6 +57,9 @@ public:
int GenerateIndirectionBranch(uint32_t cia, AsmJit::GpVar& target,
bool lk, bool likely_local);
AsmJit::GpVar read_gpu_register(uint32_t r);
void write_gpu_register(uint32_t r, AsmJit::GpVar& v);
void FillRegisters();
void SpillRegisters();
@ -117,6 +122,10 @@ private:
GlobalExports global_exports_;
xe_mutex_t* lock_;
void* gpu_this_;
void* gpu_read_;
void* gpu_write_;
AsmJit::Logger* logger_;
AsmJit::X86Assembler assembler_;
AsmJit::X86Compiler compiler_;

View File

@ -51,6 +51,11 @@ XECLEANUP:
return result_code;
}
void X64JIT::SetupGpuPointers(void* gpu_this,
void* gpu_read, void* gpu_write) {
emitter_->SetupGpuPointers(gpu_this, gpu_read, gpu_write);
}
namespace {
struct BitDescription {
uint32_t mask;

View File

@ -29,6 +29,8 @@ public:
virtual ~X64JIT();
virtual int Setup();
virtual void SetupGpuPointers(void* gpu_this,
void* gpu_read, void* gpu_write);
virtual int InitModule(ExecModule* module);
virtual int UninitModule(ExecModule* module);

View File

@ -23,3 +23,12 @@ D3D11GraphicsSystem::D3D11GraphicsSystem(const CreationParams* params) :
D3D11GraphicsSystem::~D3D11GraphicsSystem() {
}
uint64_t D3D11GraphicsSystem::ReadRegister(uint32_t r) {
XELOGGPU("ReadRegister(%.4X)", r);
return 0;
}
void D3D11GraphicsSystem::WriteRegister(uint32_t r, uint64_t value) {
XELOGGPU("WriteRegister(%.4X, %.8X)", r, value);
}

View File

@ -28,6 +28,9 @@ class D3D11GraphicsSystem : public GraphicsSystem {
public:
D3D11GraphicsSystem(const CreationParams* params);
virtual ~D3D11GraphicsSystem();
virtual uint64_t ReadRegister(uint32_t r);
virtual void WriteRegister(uint32_t r, uint64_t value);
};

View File

@ -20,6 +20,8 @@ namespace gpu {
class CreationParams {
public:
xe_memory_ref memory;
CreationParams() : memory(NULL) {}
};
@ -29,6 +31,16 @@ public:
xe_memory_ref memory();
virtual uint64_t ReadRegister(uint32_t r) = 0;
virtual void WriteRegister(uint32_t r, uint64_t value) = 0;
static uint64_t ReadRegisterThunk(GraphicsSystem* this_ptr, uint32_t r) {
return this_ptr->ReadRegister(r);
}
static void WriteRegisterThunk(GraphicsSystem* this_ptr, uint32_t r, uint64_t value) {
this_ptr->WriteRegister(r, value);
}
protected:
GraphicsSystem(const CreationParams* params);

View File

@ -23,3 +23,12 @@ NopGraphicsSystem::NopGraphicsSystem(const CreationParams* params) :
NopGraphicsSystem::~NopGraphicsSystem() {
}
uint64_t NopGraphicsSystem::ReadRegister(uint32_t r) {
XELOGGPU("ReadRegister(%.4X)", r);
return 0;
}
void NopGraphicsSystem::WriteRegister(uint32_t r, uint64_t value) {
XELOGGPU("WriteRegister(%.4X, %.8X)", r, value);
}

View File

@ -25,6 +25,9 @@ class NopGraphicsSystem : public GraphicsSystem {
public:
NopGraphicsSystem(const CreationParams* params);
virtual ~NopGraphicsSystem();
virtual uint64_t ReadRegister(uint32_t r);
virtual void WriteRegister(uint32_t r, uint64_t value);
};

View File

@ -14,6 +14,7 @@
using namespace xe;
using namespace xe::cpu;
using namespace xe::gpu;
using namespace xe::dbg;
using namespace xe::kernel;
@ -32,10 +33,11 @@ public:
private:
xe_memory_ref memory_;
shared_ptr<Backend> backend_;
shared_ptr<Processor> processor_;
shared_ptr<Runtime> runtime_;
shared_ptr<Debugger> debugger_;
shared_ptr<Backend> backend_;
shared_ptr<GraphicsSystem> graphics_system_;
shared_ptr<Processor> processor_;
shared_ptr<Runtime> runtime_;
shared_ptr<Debugger> debugger_;
};
Run::Run() {
@ -46,20 +48,26 @@ Run::~Run() {
}
int Run::Setup() {
CreationParams params;
xe_pal_options_t pal_options;
xe_zero_struct(&pal_options, sizeof(pal_options));
XEEXPECTZERO(xe_pal_init(pal_options));
backend_ = shared_ptr<Backend>(new xe::cpu::x64::X64Backend());
debugger_ = shared_ptr<Debugger>(new Debugger());
xe_memory_options_t memory_options;
xe_zero_struct(&memory_options, sizeof(memory_options));
memory_ = xe_memory_create(memory_options);
XEEXPECTNOTNULL(memory_);
backend_ = shared_ptr<Backend>(new xe::cpu::x64::X64Backend());
params.memory = memory_;
graphics_system_ = shared_ptr<GraphicsSystem>(xe::gpu::CreateNop(&params));
debugger_ = shared_ptr<Debugger>(new Debugger());
processor_ = shared_ptr<Processor>(new Processor(memory_, backend_));
processor_->set_graphics_system(graphics_system_);
XEEXPECTZERO(processor_->Setup());
runtime_ = shared_ptr<Runtime>(new Runtime(processor_, XT("")));