yuzu-emu
/
yuzu-mainline
Archived
1
0
Fork 0

Merge pull request #2139 from degasus/dma_pusher

video_core/dma_pusher: The full list of headers at once.
This commit is contained in:
bunnei 2019-02-24 04:15:49 -05:00 committed by GitHub
commit 90c780e6f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 27 deletions

View File

@ -33,18 +33,36 @@ 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"); }
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) { if (command_list_header.size == 0) {
dma_mget = dma_get; 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()) { if (!non_main) {
// We've gone through the current list, remove it from the queue // TODO (degasus): This is dead code, as dma_mget is never read.
dma_pushbuffer.pop(); dma_mget = dma_put;
dma_pushbuffer_subindex = 0;
}
} else {
// Otherwise, pushbuffer empty and IB empty or nonexistent - nothing to do
return {};
} }
return true; return true;

View File

@ -75,6 +75,8 @@ private:
GPU& gpu; GPU& gpu;
std::vector<CommandHeader> command_headers; ///< Buffer for list of commands fetched at once
std::queue<CommandList> dma_pushbuffer; ///< Queue of command lists to be processed std::queue<CommandList> dma_pushbuffer; ///< Queue of command lists to be processed
std::size_t dma_pushbuffer_subindex{}; ///< Index within a command list within the pushbuffer std::size_t dma_pushbuffer_subindex{}; ///< Index within a command list within the pushbuffer
@ -89,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