Wiring up register read/write from JIT -> GPU.
This commit is contained in:
parent
edf3a9155b
commit
ef0032ecff
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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_;
|
||||
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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(¶ms));
|
||||
|
||||
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("")));
|
||||
|
|
Loading…
Reference in New Issue