diff options
| author | bunnei <bunneidev@gmail.com> | 2019-02-24 04:15:49 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-02-24 04:15:49 -0500 | 
| commit | 90c780e6f3f035090ebffae2866f428e76801429 (patch) | |
| tree | da8852dabbff9de60b88a35a67120abbd3745710 | |
| parent | f7090bacc5c796c79fc2f871bce6145a6e9373e5 (diff) | |
| parent | 6dd40976d0eb39e9b4ac2cb7e3b78fe0a4bf0116 (diff) | |
Merge pull request #2139 from degasus/dma_pusher
video_core/dma_pusher: The full list of headers at once.
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 57 | ||||
| -rw-r--r-- | src/video_core/dma_pusher.h | 5 | 
2 files changed, 34 insertions, 28 deletions
| diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index eb9bf1878..669541b4b 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp @@ -33,18 +33,36 @@ void DmaPusher::DispatchCalls() {  }  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          if (dma_state.length_pending) { @@ -91,22 +109,11 @@ bool DmaPusher::Step() {                  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; diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h index 1097e5c49..27a36348c 100644 --- a/src/video_core/dma_pusher.h +++ b/src/video_core/dma_pusher.h @@ -75,6 +75,8 @@ private:      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::size_t dma_pushbuffer_subindex{};  ///< Index within a command list within the pushbuffer @@ -89,11 +91,8 @@ private:      DmaState dma_state{};      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      bool ib_enable{true}; ///< IB mode enabled -    bool non_main{};      ///< non-main pushbuffer active  };  } // namespace Tegra | 
