Skip to content
Snippets Groups Projects
Commit 6dd40976 authored by Markus Wick's avatar Markus Wick
Browse files

video_core/dma_pusher: Simplyfy Step() logic.

As fetching command list headers and and the list of command headers is a fixed 1:1 relation now, they can be implemented within a single call.
This cleans up the Step() logic quite a bit.
parent 717394c9
No related branches found
No related tags found
No related merge requests found
...@@ -33,88 +33,87 @@ void DmaPusher::DispatchCalls() { ...@@ -33,88 +33,87 @@ void DmaPusher::DispatchCalls() {
} }
bool DmaPusher::Step() { bool DmaPusher::Step() {
if (dma_get != dma_put) { if (!ib_enable || dma_pushbuffer.empty()) {
// Push buffer non-empty, read a word // pushbuffer empty and IB empty or nonexistent - nothing to do
const auto address = gpu.MemoryManager().GpuToCpuAddress(dma_get); return false;
ASSERT_MSG(address, "Invalid GPU address"); }
GPUVAddr size = dma_put - dma_get; const CommandList& command_list{dma_pushbuffer.front()};
ASSERT_MSG(size % sizeof(CommandHeader) == 0, "Invalid aligned GPU addresses"); const CommandListHeader& command_list_header{command_list[dma_pushbuffer_subindex++]};
command_headers.resize(size / sizeof(CommandHeader)); GPUVAddr dma_get = command_list_header.addr;
GPUVAddr dma_put = dma_get + command_list_header.size * sizeof(u32);
Memory::ReadBlock(*address, command_headers.data(), size); bool non_main = command_list_header.is_non_main;
for (const CommandHeader& command_header : command_headers) { if (dma_pushbuffer_subindex >= command_list.size()) {
// We've gone through the current list, remove it from the queue
// now, see if we're in the middle of a command dma_pushbuffer.pop();
if (dma_state.length_pending) { dma_pushbuffer_subindex = 0;
// Second word of long non-inc methods command - method count }
dma_state.length_pending = 0;
dma_state.method_count = command_header.method_count_; if (command_list_header.size == 0) {
} else if (dma_state.method_count) { return true;
// Data word of methods command }
CallMethod(command_header.argument);
// Push buffer non-empty, read a word
if (!dma_state.non_incrementing) { const auto address = gpu.MemoryManager().GpuToCpuAddress(dma_get);
dma_state.method++; ASSERT_MSG(address, "Invalid GPU address");
}
command_headers.resize(command_list_header.size);
if (dma_increment_once) {
dma_state.non_incrementing = true; Memory::ReadBlock(*address, command_headers.data(), command_list_header.size * sizeof(u32));
}
for (const CommandHeader& command_header : command_headers) {
dma_state.method_count--;
} else { // now, see if we're in the middle of a command
// No command active - this is the first word of a new one if (dma_state.length_pending) {
switch (command_header.mode) { // Second word of long non-inc methods command - method count
case SubmissionMode::Increasing: dma_state.length_pending = 0;
SetState(command_header); dma_state.method_count = command_header.method_count_;
dma_state.non_incrementing = false; } else if (dma_state.method_count) {
dma_increment_once = false; // Data word of methods command
break; CallMethod(command_header.argument);
case SubmissionMode::NonIncreasing:
SetState(command_header); if (!dma_state.non_incrementing) {
dma_state.non_incrementing = true; dma_state.method++;
dma_increment_once = false;
break;
case SubmissionMode::Inline:
dma_state.method = command_header.method;
dma_state.subchannel = command_header.subchannel;
CallMethod(command_header.arg_count);
dma_state.non_incrementing = true;
dma_increment_once = false;
break;
case SubmissionMode::IncreaseOnce:
SetState(command_header);
dma_state.non_incrementing = false;
dma_increment_once = true;
break;
}
} }
}
dma_get = dma_put; if (dma_increment_once) {
dma_state.non_incrementing = true;
}
if (!non_main) { dma_state.method_count--;
// TODO (degasus): This is dead code, as dma_mget is never read. } else {
dma_mget = dma_get; // No command active - this is the first word of a new one
} switch (command_header.mode) {
} else if (ib_enable && !dma_pushbuffer.empty()) { case SubmissionMode::Increasing:
// Current pushbuffer empty, but we have more IB entries to read SetState(command_header);
const CommandList& command_list{dma_pushbuffer.front()}; dma_state.non_incrementing = false;
const CommandListHeader& command_list_header{command_list[dma_pushbuffer_subindex++]}; dma_increment_once = false;
dma_get = command_list_header.addr; break;
dma_put = dma_get + command_list_header.size * sizeof(u32); case SubmissionMode::NonIncreasing:
non_main = command_list_header.is_non_main; SetState(command_header);
dma_state.non_incrementing = true;
if (dma_pushbuffer_subindex >= command_list.size()) { dma_increment_once = false;
// We've gone through the current list, remove it from the queue break;
dma_pushbuffer.pop(); case SubmissionMode::Inline:
dma_pushbuffer_subindex = 0; dma_state.method = command_header.method;
dma_state.subchannel = command_header.subchannel;
CallMethod(command_header.arg_count);
dma_state.non_incrementing = true;
dma_increment_once = false;
break;
case SubmissionMode::IncreaseOnce:
SetState(command_header);
dma_state.non_incrementing = false;
dma_increment_once = true;
break;
}
} }
} 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;
......
...@@ -91,11 +91,8 @@ private: ...@@ -91,11 +91,8 @@ private:
DmaState dma_state{}; DmaState dma_state{};
bool dma_increment_once{}; bool dma_increment_once{};
GPUVAddr dma_put{}; ///< pushbuffer current end address
GPUVAddr dma_get{}; ///< pushbuffer current read address
GPUVAddr dma_mget{}; ///< main pushbuffer last read address GPUVAddr dma_mget{}; ///< main pushbuffer last read address
bool ib_enable{true}; ///< IB mode enabled bool ib_enable{true}; ///< IB mode enabled
bool non_main{}; ///< non-main pushbuffer active
}; };
} // namespace Tegra } // namespace Tegra
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment