|
@@ -33,18 +33,36 @@ void DmaPusher::DispatchCalls() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool DmaPusher::Step() {
|
|
bool DmaPusher::Step() {
|
|
|
- if (dma_get != dma_put) {
|
|
|
|
|
- // Push buffer non-empty, read a word
|
|
|
|
|
- const auto address = gpu.MemoryManager().GpuToCpuAddress(dma_get);
|
|
|
|
|
- ASSERT_MSG(address, "Invalid GPU address");
|
|
|
|
|
|
|
+ if (!ib_enable || dma_pushbuffer.empty()) {
|
|
|
|
|
+ // pushbuffer empty and IB empty or nonexistent - nothing to do
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- const CommandHeader command_header{Memory::Read32(*address)};
|
|
|
|
|
|
|
+ const CommandList& command_list{dma_pushbuffer.front()};
|
|
|
|
|
+ const CommandListHeader& command_list_header{command_list[dma_pushbuffer_subindex++]};
|
|
|
|
|
+ GPUVAddr dma_get = command_list_header.addr;
|
|
|
|
|
+ GPUVAddr dma_put = dma_get + command_list_header.size * sizeof(u32);
|
|
|
|
|
+ bool non_main = command_list_header.is_non_main;
|
|
|
|
|
|
|
|
- dma_get += sizeof(u32);
|
|
|
|
|
|
|
+ if (dma_pushbuffer_subindex >= command_list.size()) {
|
|
|
|
|
+ // We've gone through the current list, remove it from the queue
|
|
|
|
|
+ dma_pushbuffer.pop();
|
|
|
|
|
+ dma_pushbuffer_subindex = 0;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (!non_main) {
|
|
|
|
|
- dma_mget = dma_get;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (command_list_header.size == 0) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Push buffer non-empty, read a word
|
|
|
|
|
+ const auto address = gpu.MemoryManager().GpuToCpuAddress(dma_get);
|
|
|
|
|
+ ASSERT_MSG(address, "Invalid GPU address");
|
|
|
|
|
+
|
|
|
|
|
+ command_headers.resize(command_list_header.size);
|
|
|
|
|
+
|
|
|
|
|
+ Memory::ReadBlock(*address, command_headers.data(), command_list_header.size * sizeof(u32));
|
|
|
|
|
+
|
|
|
|
|
+ for (const CommandHeader& command_header : command_headers) {
|
|
|
|
|
|
|
|
// now, see if we're in the middle of a command
|
|
// now, see if we're in the middle of a command
|
|
|
if (dma_state.length_pending) {
|
|
if (dma_state.length_pending) {
|
|
@@ -91,22 +109,11 @@ bool DmaPusher::Step() {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- } else if (ib_enable && !dma_pushbuffer.empty()) {
|
|
|
|
|
- // Current pushbuffer empty, but we have more IB entries to read
|
|
|
|
|
- const CommandList& command_list{dma_pushbuffer.front()};
|
|
|
|
|
- const CommandListHeader& command_list_header{command_list[dma_pushbuffer_subindex++]};
|
|
|
|
|
- dma_get = command_list_header.addr;
|
|
|
|
|
- dma_put = dma_get + command_list_header.size * sizeof(u32);
|
|
|
|
|
- non_main = command_list_header.is_non_main;
|
|
|
|
|
-
|
|
|
|
|
- if (dma_pushbuffer_subindex >= command_list.size()) {
|
|
|
|
|
- // We've gone through the current list, remove it from the queue
|
|
|
|
|
- dma_pushbuffer.pop();
|
|
|
|
|
- dma_pushbuffer_subindex = 0;
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- // Otherwise, pushbuffer empty and IB empty or nonexistent - nothing to do
|
|
|
|
|
- return {};
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!non_main) {
|
|
|
|
|
+ // TODO (degasus): This is dead code, as dma_mget is never read.
|
|
|
|
|
+ dma_mget = dma_put;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
return true;
|