diff options
| author | 2019-02-19 10:26:58 +0100 | |
|---|---|---|
| committer | 2019-02-19 10:28:42 +0100 | |
| commit | 6dd40976d0eb39e9b4ac2cb7e3b78fe0a4bf0116 (patch) | |
| tree | f13452d784190c570118f6bb22dec6ea91c6012a /src | |
| parent | video_core/dma_pusher: The full list of headers at once. (diff) | |
| download | yuzu-6dd40976d0eb39e9b4ac2cb7e3b78fe0a4bf0116.tar.gz yuzu-6dd40976d0eb39e9b4ac2cb7e3b78fe0a4bf0116.tar.xz yuzu-6dd40976d0eb39e9b4ac2cb7e3b78fe0a4bf0116.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 155 | ||||
| -rw-r--r-- | src/video_core/dma_pusher.h | 3 |
2 files changed, 77 insertions, 81 deletions
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 654e4d9aa..669541b4b 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp | |||
| @@ -33,88 +33,87 @@ void DmaPusher::DispatchCalls() { | |||
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | bool DmaPusher::Step() { | 35 | bool DmaPusher::Step() { |
| 36 | if (dma_get != dma_put) { | 36 | if (!ib_enable || dma_pushbuffer.empty()) { |
| 37 | // Push buffer non-empty, read a word | 37 | // pushbuffer empty and IB empty or nonexistent - nothing to do |
| 38 | const auto address = gpu.MemoryManager().GpuToCpuAddress(dma_get); | 38 | return false; |
| 39 | ASSERT_MSG(address, "Invalid GPU address"); | 39 | } |
| 40 | 40 | ||
| 41 | GPUVAddr size = dma_put - dma_get; | 41 | const CommandList& command_list{dma_pushbuffer.front()}; |
| 42 | ASSERT_MSG(size % sizeof(CommandHeader) == 0, "Invalid aligned GPU addresses"); | 42 | const CommandListHeader& command_list_header{command_list[dma_pushbuffer_subindex++]}; |
| 43 | command_headers.resize(size / sizeof(CommandHeader)); | 43 | GPUVAddr dma_get = command_list_header.addr; |
| 44 | 44 | GPUVAddr dma_put = dma_get + command_list_header.size * sizeof(u32); | |
| 45 | Memory::ReadBlock(*address, command_headers.data(), size); | 45 | bool non_main = command_list_header.is_non_main; |
| 46 | 46 | ||
| 47 | for (const CommandHeader& command_header : command_headers) { | 47 | if (dma_pushbuffer_subindex >= command_list.size()) { |
| 48 | 48 | // We've gone through the current list, remove it from the queue | |
| 49 | // now, see if we're in the middle of a command | 49 | dma_pushbuffer.pop(); |
| 50 | if (dma_state.length_pending) { | 50 | dma_pushbuffer_subindex = 0; |
| 51 | // Second word of long non-inc methods command - method count | 51 | } |
| 52 | dma_state.length_pending = 0; | 52 | |
| 53 | dma_state.method_count = command_header.method_count_; | 53 | if (command_list_header.size == 0) { |
| 54 | } else if (dma_state.method_count) { | 54 | return true; |
| 55 | // Data word of methods command | 55 | } |
| 56 | CallMethod(command_header.argument); | 56 | |
| 57 | 57 | // Push buffer non-empty, read a word | |
| 58 | if (!dma_state.non_incrementing) { | 58 | const auto address = gpu.MemoryManager().GpuToCpuAddress(dma_get); |
| 59 | dma_state.method++; | 59 | ASSERT_MSG(address, "Invalid GPU address"); |
| 60 | } | 60 | |
| 61 | 61 | command_headers.resize(command_list_header.size); | |
| 62 | if (dma_increment_once) { | 62 | |
| 63 | dma_state.non_incrementing = true; | 63 | Memory::ReadBlock(*address, command_headers.data(), command_list_header.size * sizeof(u32)); |
| 64 | } | 64 | |
| 65 | 65 | for (const CommandHeader& command_header : command_headers) { | |
| 66 | dma_state.method_count--; | 66 | |
| 67 | } else { | 67 | // now, see if we're in the middle of a command |
| 68 | // No command active - this is the first word of a new one | 68 | if (dma_state.length_pending) { |
| 69 | switch (command_header.mode) { | 69 | // Second word of long non-inc methods command - method count |
| 70 | case SubmissionMode::Increasing: | 70 | dma_state.length_pending = 0; |
| 71 | SetState(command_header); | 71 | dma_state.method_count = command_header.method_count_; |
| 72 | dma_state.non_incrementing = false; | 72 | } else if (dma_state.method_count) { |
| 73 | dma_increment_once = false; | 73 | // Data word of methods command |
| 74 | break; | 74 | CallMethod(command_header.argument); |
| 75 | case SubmissionMode::NonIncreasing: | 75 | |
| 76 | SetState(command_header); | 76 | if (!dma_state.non_incrementing) { |
| 77 | dma_state.non_incrementing = true; | 77 | dma_state.method++; |
| 78 | dma_increment_once = false; | ||
| 79 | break; | ||
| 80 | case SubmissionMode::Inline: | ||
| 81 | dma_state.method = command_header.method; | ||
| 82 | dma_state.subchannel = command_header.subchannel; | ||
| 83 | CallMethod(command_header.arg_count); | ||
| 84 | dma_state.non_incrementing = true; | ||
| 85 | dma_increment_once = false; | ||
| 86 | break; | ||
| 87 | case SubmissionMode::IncreaseOnce: | ||
| 88 | SetState(command_header); | ||
| 89 | dma_state.non_incrementing = false; | ||
| 90 | dma_increment_once = true; | ||
| 91 | break; | ||
| 92 | } | ||
| 93 | } | 78 | } |
| 94 | } | ||
| 95 | 79 | ||
| 96 | dma_get = dma_put; | 80 | if (dma_increment_once) { |
| 81 | dma_state.non_incrementing = true; | ||
| 82 | } | ||
| 97 | 83 | ||
| 98 | if (!non_main) { | 84 | dma_state.method_count--; |
| 99 | // TODO (degasus): This is dead code, as dma_mget is never read. | 85 | } else { |
| 100 | dma_mget = dma_get; | 86 | // No command active - this is the first word of a new one |
| 101 | } | 87 | switch (command_header.mode) { |
| 102 | } else if (ib_enable && !dma_pushbuffer.empty()) { | 88 | case SubmissionMode::Increasing: |
| 103 | // Current pushbuffer empty, but we have more IB entries to read | 89 | SetState(command_header); |
| 104 | const CommandList& command_list{dma_pushbuffer.front()}; | 90 | dma_state.non_incrementing = false; |
| 105 | const CommandListHeader& command_list_header{command_list[dma_pushbuffer_subindex++]}; | 91 | dma_increment_once = false; |
| 106 | dma_get = command_list_header.addr; | 92 | break; |
| 107 | dma_put = dma_get + command_list_header.size * sizeof(u32); | 93 | case SubmissionMode::NonIncreasing: |
| 108 | non_main = command_list_header.is_non_main; | 94 | SetState(command_header); |
| 109 | 95 | dma_state.non_incrementing = true; | |
| 110 | if (dma_pushbuffer_subindex >= command_list.size()) { | 96 | dma_increment_once = false; |
| 111 | // We've gone through the current list, remove it from the queue | 97 | break; |
| 112 | dma_pushbuffer.pop(); | 98 | case SubmissionMode::Inline: |
| 113 | dma_pushbuffer_subindex = 0; | 99 | dma_state.method = command_header.method; |
| 100 | dma_state.subchannel = command_header.subchannel; | ||
| 101 | CallMethod(command_header.arg_count); | ||
| 102 | dma_state.non_incrementing = true; | ||
| 103 | dma_increment_once = false; | ||
| 104 | break; | ||
| 105 | case SubmissionMode::IncreaseOnce: | ||
| 106 | SetState(command_header); | ||
| 107 | dma_state.non_incrementing = false; | ||
| 108 | dma_increment_once = true; | ||
| 109 | break; | ||
| 110 | } | ||
| 114 | } | 111 | } |
| 115 | } else { | 112 | } |
| 116 | // Otherwise, pushbuffer empty and IB empty or nonexistent - nothing to do | 113 | |
| 117 | return {}; | 114 | if (!non_main) { |
| 115 | // TODO (degasus): This is dead code, as dma_mget is never read. | ||
| 116 | dma_mget = dma_put; | ||
| 118 | } | 117 | } |
| 119 | 118 | ||
| 120 | return true; | 119 | return true; |
diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h index 14b23b1d7..27a36348c 100644 --- a/src/video_core/dma_pusher.h +++ b/src/video_core/dma_pusher.h | |||
| @@ -91,11 +91,8 @@ private: | |||
| 91 | DmaState dma_state{}; | 91 | DmaState dma_state{}; |
| 92 | bool dma_increment_once{}; | 92 | bool dma_increment_once{}; |
| 93 | 93 | ||
| 94 | GPUVAddr dma_put{}; ///< pushbuffer current end address | ||
| 95 | GPUVAddr dma_get{}; ///< pushbuffer current read address | ||
| 96 | GPUVAddr dma_mget{}; ///< main pushbuffer last read address | 94 | GPUVAddr dma_mget{}; ///< main pushbuffer last read address |
| 97 | bool ib_enable{true}; ///< IB mode enabled | 95 | bool ib_enable{true}; ///< IB mode enabled |
| 98 | bool non_main{}; ///< non-main pushbuffer active | ||
| 99 | }; | 96 | }; |
| 100 | 97 | ||
| 101 | } // namespace Tegra | 98 | } // namespace Tegra |