Trying to setup writeback and add basic secondary command execution.

This commit is contained in:
Ben Vanik
2013-06-01 03:08:31 -07:00
parent 5b0fa8f17e
commit ba16a0d847
7 changed files with 105 additions and 29 deletions

View File

@@ -43,6 +43,17 @@ void RingBufferWorker::Initialize(uint32_t ptr, uint32_t page_count) {
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) {
write_ptr_index_ = value;
SetEvent(write_ptr_index_event_);
@@ -74,22 +85,30 @@ void RingBufferWorker::ThreadStart() {
while (true) {
uint32_t command = READ_UINT32();
XELOGGPU("Command(%.8X)", command);
switch (command) {
case 0xC0114800:
// Init packet.
// Will have 18-19 ops after it. Maybe.
for (int n = 0; n < 18; n++) {
READ_UINT32();
{
// Init packet.
// Will have 18-19 ops after it. Maybe.
XELOGGPU("Command(%.8X): init packet", command);
for (int n = 0; n < 18; n++) {
READ_UINT32();
}
}
break;
case 0xC0013F00:
// Kick segment.
uint32_t segment_ptr = READ_UINT32();
uint32_t length = READ_UINT32();
XELOGGPU("Command(%.8X): kick segment %.8X (%db)",
command, segment_ptr, length);
{
// Kick segment.
uint32_t segment_ptr = READ_UINT32();
uint32_t length = READ_UINT32();
XELOGGPU("Command(%.8X): kick segment %.8X (%db)",
command, segment_ptr, length * 4);
ExecuteSegment(segment_ptr, length);
}
break;
default:
XELOGGPU("Command(%.8X): unknown primary buffer command", command);
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_);
}
}
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);
}
}