Trying to setup writeback and add basic secondary command execution.
This commit is contained in:
parent
5b0fa8f17e
commit
ba16a0d847
|
@ -29,12 +29,14 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory map:
|
* Memory map:
|
||||||
* 0x00000000 - 0x40000000 (1024mb) - virtual 4k pages
|
* 0x00000000 - 0x3FFFFFFF (1024mb) - virtual 4k pages
|
||||||
* 0x40000000 - 0x80000000 (1024mb) - virtual 64k pages
|
* 0x40000000 - 0x7FFFFFFF (1024mb) - virtual 64k pages
|
||||||
* 0x80000000 - 0x8C000000 ( 192mb) - xex 64k pages
|
* 0x80000000 - 0x8BFFFFFF ( 192mb) - xex 64k pages
|
||||||
* 0x8C000000 - 0x90000000 ( 64mb) - xex 64k pages (encrypted)
|
* 0x8C000000 - 0x8FFFFFFF ( 64mb) - xex 64k pages (encrypted)
|
||||||
* 0x90000000 - 0xA0000000 ( 256mb) - xex 4k pages
|
* 0x90000000 - 0x9FFFFFFF ( 256mb) - xex 4k pages
|
||||||
* 0xA0000000 - 0xC0000000 ( 512mb) - physical 64k pages
|
* 0xA0000000 - 0xBFFFFFFF ( 512mb) - physical 64k pages
|
||||||
|
* 0xC0000000 - 0xDFFFFFFF - physical 16mb pages
|
||||||
|
* 0xE0000000 - 0xFFFFFFFF - physical 4k pages
|
||||||
*
|
*
|
||||||
* We use the host OS to create an entire addressable range for this. That way
|
* We use the host OS to create an entire addressable range for this. That way
|
||||||
* we don't have to emulate a TLB. It'd be really cool to pass through page
|
* we don't have to emulate a TLB. It'd be really cool to pass through page
|
||||||
|
|
|
@ -37,6 +37,11 @@ void GraphicsSystem::InitializeRingBuffer(uint32_t ptr, uint32_t page_count) {
|
||||||
worker_->Initialize(ptr, page_count);
|
worker_->Initialize(ptr, page_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphicsSystem::EnableReadPointerWriteBack(uint32_t ptr,
|
||||||
|
uint32_t block_size) {
|
||||||
|
worker_->EnableReadPointerWriteBack(ptr, block_size);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t GraphicsSystem::ReadRegister(uint32_t r) {
|
uint64_t GraphicsSystem::ReadRegister(uint32_t r) {
|
||||||
XELOGGPU("ReadRegister(%.4X)", r);
|
XELOGGPU("ReadRegister(%.4X)", r);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -35,6 +35,7 @@ public:
|
||||||
|
|
||||||
virtual void Initialize() = 0;
|
virtual void Initialize() = 0;
|
||||||
void InitializeRingBuffer(uint32_t ptr, uint32_t page_count);
|
void InitializeRingBuffer(uint32_t ptr, uint32_t page_count);
|
||||||
|
void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size);
|
||||||
|
|
||||||
virtual uint64_t ReadRegister(uint32_t r);
|
virtual uint64_t ReadRegister(uint32_t r);
|
||||||
virtual void WriteRegister(uint32_t r, uint64_t value);
|
virtual void WriteRegister(uint32_t r, uint64_t value);
|
||||||
|
|
|
@ -43,6 +43,17 @@ void RingBufferWorker::Initialize(uint32_t ptr, uint32_t page_count) {
|
||||||
xe_thread_start(thread_);
|
xe_thread_start(thread_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RingBufferWorker::EnableReadPointerWriteBack(uint32_t ptr,
|
||||||
|
uint32_t block_size) {
|
||||||
|
// CP_RB_RPTR_ADDR Ring Buffer Read Pointer Address 0x70C
|
||||||
|
// ptr = RB_RPTR_ADDR, pointer to write back the address to.
|
||||||
|
read_ptr_writeback_ptr_ = (primary_buffer_ptr_ & ~0x1FFFFFFF) + ptr;
|
||||||
|
// CP_RB_CNTL Ring Buffer Control 0x704
|
||||||
|
// block_size = RB_BLKSZ, number of quadwords read between updates of the
|
||||||
|
// read pointer.
|
||||||
|
read_ptr_update_freq_ = (uint32_t)pow(2.0, (double)block_size) / 4;
|
||||||
|
}
|
||||||
|
|
||||||
void RingBufferWorker::UpdateWritePointer(uint32_t value) {
|
void RingBufferWorker::UpdateWritePointer(uint32_t value) {
|
||||||
write_ptr_index_ = value;
|
write_ptr_index_ = value;
|
||||||
SetEvent(write_ptr_index_event_);
|
SetEvent(write_ptr_index_event_);
|
||||||
|
@ -74,22 +85,30 @@ void RingBufferWorker::ThreadStart() {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
uint32_t command = READ_UINT32();
|
uint32_t command = READ_UINT32();
|
||||||
XELOGGPU("Command(%.8X)", command);
|
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case 0xC0114800:
|
case 0xC0114800:
|
||||||
|
{
|
||||||
// Init packet.
|
// Init packet.
|
||||||
// Will have 18-19 ops after it. Maybe.
|
// Will have 18-19 ops after it. Maybe.
|
||||||
|
XELOGGPU("Command(%.8X): init packet", command);
|
||||||
for (int n = 0; n < 18; n++) {
|
for (int n = 0; n < 18; n++) {
|
||||||
READ_UINT32();
|
READ_UINT32();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0xC0013F00:
|
case 0xC0013F00:
|
||||||
|
{
|
||||||
// Kick segment.
|
// Kick segment.
|
||||||
uint32_t segment_ptr = READ_UINT32();
|
uint32_t segment_ptr = READ_UINT32();
|
||||||
uint32_t length = READ_UINT32();
|
uint32_t length = READ_UINT32();
|
||||||
XELOGGPU("Command(%.8X): kick segment %.8X (%db)",
|
XELOGGPU("Command(%.8X): kick segment %.8X (%db)",
|
||||||
command, segment_ptr, length);
|
command, segment_ptr, length * 4);
|
||||||
|
ExecuteSegment(segment_ptr, length);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
XELOGGPU("Command(%.8X): unknown primary buffer command", command);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +117,26 @@ void RingBufferWorker::ThreadStart() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(benvanik): use read_ptr_update_freq_ and only issue after moving
|
||||||
|
// that many indices.
|
||||||
|
if (read_ptr_writeback_ptr_) {
|
||||||
|
XESETUINT32BE(p + read_ptr_writeback_ptr_, read_ptr_index_);
|
||||||
|
}
|
||||||
SetEvent(read_ptr_index_event_);
|
SetEvent(read_ptr_index_event_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RingBufferWorker::ExecuteSegment(uint32_t ptr, uint32_t length) {
|
||||||
|
uint8_t* p = xe_memory_addr(memory_);
|
||||||
|
|
||||||
|
// Adjust pointer base.
|
||||||
|
ptr += (primary_buffer_ptr_ & ~0x1FFFFFFF);
|
||||||
|
|
||||||
|
XELOGGPU("CommandList(%.8X): executing %d commands", ptr, length);
|
||||||
|
|
||||||
|
// Execute commands!
|
||||||
|
for (uint32_t n = 0; n < length; n++) {
|
||||||
|
uint32_t command = XEGETUINT32BE(p + ptr + n * 4);
|
||||||
|
XELOGGPU(" Command(%.8X)", command);
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ public:
|
||||||
xe_memory_ref memory();
|
xe_memory_ref memory();
|
||||||
|
|
||||||
void Initialize(uint32_t ptr, uint32_t page_count);
|
void Initialize(uint32_t ptr, uint32_t page_count);
|
||||||
|
void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size);
|
||||||
|
|
||||||
void UpdateWritePointer(uint32_t value);
|
void UpdateWritePointer(uint32_t value);
|
||||||
|
|
||||||
|
@ -33,19 +34,22 @@ protected:
|
||||||
this_ptr->ThreadStart();
|
this_ptr->ThreadStart();
|
||||||
}
|
}
|
||||||
void ThreadStart();
|
void ThreadStart();
|
||||||
|
void ExecuteSegment(uint32_t ptr, uint32_t length);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
xe_memory_ref memory_;
|
xe_memory_ref memory_;
|
||||||
xe_thread_ref thread_;
|
xe_thread_ref thread_;
|
||||||
bool running_;
|
bool running_;
|
||||||
HANDLE read_ptr_index_event_;
|
|
||||||
HANDLE write_ptr_index_event_;
|
|
||||||
|
|
||||||
uint32_t primary_buffer_ptr_;
|
uint32_t primary_buffer_ptr_;
|
||||||
uint32_t primary_buffer_size_;
|
uint32_t primary_buffer_size_;
|
||||||
uint32_t secondary_buffer_ptr_;
|
|
||||||
uint32_t secondary_buffer_size_;
|
HANDLE read_ptr_index_event_;
|
||||||
uint32_t read_ptr_index_;
|
uint32_t read_ptr_index_;
|
||||||
|
uint32_t read_ptr_update_freq_;
|
||||||
|
uint32_t read_ptr_writeback_ptr_;
|
||||||
|
|
||||||
|
HANDLE write_ptr_index_event_;
|
||||||
uint32_t write_ptr_index_;
|
uint32_t write_ptr_index_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -178,21 +178,45 @@ SHIM_CALL VdInitializeRingBuffer_shim(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// void VdEnableRingBufferRPtrWriteBack
|
void xeVdEnableRingBufferRPtrWriteBack(uint32_t ptr, uint32_t block_size) {
|
||||||
// r3 = ? pointer? doesn't look like a valid one
|
KernelState* state = shared_kernel_state_;
|
||||||
// r4 = 6, usually --- <=19
|
XEASSERTNOTNULL(state);
|
||||||
// Same value used to calculate the pointer is later written to
|
GraphicsSystem* gs = state->processor()->graphics_system().get();
|
||||||
// Maybe GPU-memory relative?
|
if (!gs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// r4 = 6, usually --- <=19
|
||||||
|
gs->EnableReadPointerWriteBack(ptr, block_size);
|
||||||
|
|
||||||
|
ptr += 0x20000000;
|
||||||
|
printf("%.8X", ptr);
|
||||||
|
// 0x0110343c
|
||||||
|
|
||||||
|
//((p + 0x3C) & 0x1FFFFFFF) + ((((p + 0x3C) >> 20) + 0x200) & 0x1000)
|
||||||
|
//also 0x3C offset into WriteBacks is PrimaryRingBufferReadIndex
|
||||||
|
//(1:17:38 AM) Rick: .text:8201B348 lwz r11, 0x2B10(r31)
|
||||||
|
//(1:17:38 AM) Rick: .text:8201B34C addi r11, r11, 0x3C
|
||||||
|
//(1:17:38 AM) Rick: .text:8201B350 srwi r10, r11, 20 # r10 = r11 >> 20
|
||||||
|
//(1:17:38 AM) Rick: .text:8201B354 clrlwi r11, r11, 3 # r11 = r11 & 0x1FFFFFFF
|
||||||
|
//(1:17:38 AM) Rick: .text:8201B358 addi r10, r10, 0x200
|
||||||
|
//(1:17:39 AM) Rick: .text:8201B35C rlwinm r10, r10, 0,19,19 # r10 = r10 & 0x1000
|
||||||
|
//(1:17:39 AM) Rick: .text:8201B360 add r3, r10, r11
|
||||||
|
//(1:17:39 AM) Rick: .text:8201B364 bl VdEnableRingBufferRPtrWriteBack
|
||||||
|
// TODO(benvanik): something?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim(
|
SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim(
|
||||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
uint32_t ptr = SHIM_GET_ARG_32(0);
|
uint32_t ptr = SHIM_GET_ARG_32(0);
|
||||||
uint32_t unk1 = SHIM_GET_ARG_32(1);
|
uint32_t block_size = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
"VdEnableRingBufferRPtrWriteBack(%.8X, %.8X)",
|
"VdEnableRingBufferRPtrWriteBack(%.8X, %.8X)",
|
||||||
ptr, unk1);
|
ptr, block_size);
|
||||||
|
|
||||||
// TODO(benvanik): something?
|
xeVdEnableRingBufferRPtrWriteBack(ptr, block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ void xeVdQueryVideoMode(X_VIDEO_MODE *video_mode, bool swap);
|
||||||
void xeVdInitializeEngines(uint32_t unk0, uint32_t callback, uint32_t unk1,
|
void xeVdInitializeEngines(uint32_t unk0, uint32_t callback, uint32_t unk1,
|
||||||
uint32_t unk2_ptr, uint32_t unk3_ptr);
|
uint32_t unk2_ptr, uint32_t unk3_ptr);
|
||||||
void xeVdSetGraphicsInterruptCallback(uint32_t callback, uint32_t user_data);
|
void xeVdSetGraphicsInterruptCallback(uint32_t callback, uint32_t user_data);
|
||||||
|
void xeVdEnableRingBufferRPtrWriteBack(uint32_t ptr, uint32_t block_size);
|
||||||
|
|
||||||
|
|
||||||
} // namespace xboxkrnl
|
} // namespace xboxkrnl
|
||||||
|
|
Loading…
Reference in New Issue