diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 104 | ||||
| -rw-r--r-- | src/video_core/dma_pusher.h | 2 |
2 files changed, 58 insertions, 48 deletions
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index eb9bf1878..654e4d9aa 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp | |||
| @@ -38,59 +38,67 @@ bool DmaPusher::Step() { | |||
| 38 | const auto address = gpu.MemoryManager().GpuToCpuAddress(dma_get); | 38 | const auto address = gpu.MemoryManager().GpuToCpuAddress(dma_get); |
| 39 | ASSERT_MSG(address, "Invalid GPU address"); | 39 | ASSERT_MSG(address, "Invalid GPU address"); |
| 40 | 40 | ||
| 41 | const CommandHeader command_header{Memory::Read32(*address)}; | 41 | GPUVAddr size = dma_put - dma_get; |
| 42 | ASSERT_MSG(size % sizeof(CommandHeader) == 0, "Invalid aligned GPU addresses"); | ||
| 43 | command_headers.resize(size / sizeof(CommandHeader)); | ||
| 44 | |||
| 45 | Memory::ReadBlock(*address, command_headers.data(), size); | ||
| 46 | |||
| 47 | for (const CommandHeader& command_header : command_headers) { | ||
| 48 | |||
| 49 | // now, see if we're in the middle of a command | ||
| 50 | if (dma_state.length_pending) { | ||
| 51 | // Second word of long non-inc methods command - method count | ||
| 52 | dma_state.length_pending = 0; | ||
| 53 | dma_state.method_count = command_header.method_count_; | ||
| 54 | } else if (dma_state.method_count) { | ||
| 55 | // Data word of methods command | ||
| 56 | CallMethod(command_header.argument); | ||
| 57 | |||
| 58 | if (!dma_state.non_incrementing) { | ||
| 59 | dma_state.method++; | ||
| 60 | } | ||
| 61 | |||
| 62 | if (dma_increment_once) { | ||
| 63 | dma_state.non_incrementing = true; | ||
| 64 | } | ||
| 65 | |||
| 66 | dma_state.method_count--; | ||
| 67 | } else { | ||
| 68 | // No command active - this is the first word of a new one | ||
| 69 | switch (command_header.mode) { | ||
| 70 | case SubmissionMode::Increasing: | ||
| 71 | SetState(command_header); | ||
| 72 | dma_state.non_incrementing = false; | ||
| 73 | dma_increment_once = false; | ||
| 74 | break; | ||
| 75 | case SubmissionMode::NonIncreasing: | ||
| 76 | SetState(command_header); | ||
| 77 | dma_state.non_incrementing = true; | ||
| 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 | } | ||
| 94 | } | ||
| 42 | 95 | ||
| 43 | dma_get += sizeof(u32); | 96 | dma_get = dma_put; |
| 44 | 97 | ||
| 45 | if (!non_main) { | 98 | if (!non_main) { |
| 99 | // TODO (degasus): This is dead code, as dma_mget is never read. | ||
| 46 | dma_mget = dma_get; | 100 | dma_mget = dma_get; |
| 47 | } | 101 | } |
| 48 | |||
| 49 | // now, see if we're in the middle of a command | ||
| 50 | if (dma_state.length_pending) { | ||
| 51 | // Second word of long non-inc methods command - method count | ||
| 52 | dma_state.length_pending = 0; | ||
| 53 | dma_state.method_count = command_header.method_count_; | ||
| 54 | } else if (dma_state.method_count) { | ||
| 55 | // Data word of methods command | ||
| 56 | CallMethod(command_header.argument); | ||
| 57 | |||
| 58 | if (!dma_state.non_incrementing) { | ||
| 59 | dma_state.method++; | ||
| 60 | } | ||
| 61 | |||
| 62 | if (dma_increment_once) { | ||
| 63 | dma_state.non_incrementing = true; | ||
| 64 | } | ||
| 65 | |||
| 66 | dma_state.method_count--; | ||
| 67 | } else { | ||
| 68 | // No command active - this is the first word of a new one | ||
| 69 | switch (command_header.mode) { | ||
| 70 | case SubmissionMode::Increasing: | ||
| 71 | SetState(command_header); | ||
| 72 | dma_state.non_incrementing = false; | ||
| 73 | dma_increment_once = false; | ||
| 74 | break; | ||
| 75 | case SubmissionMode::NonIncreasing: | ||
| 76 | SetState(command_header); | ||
| 77 | dma_state.non_incrementing = true; | ||
| 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 | } | ||
| 94 | } else if (ib_enable && !dma_pushbuffer.empty()) { | 102 | } else if (ib_enable && !dma_pushbuffer.empty()) { |
| 95 | // Current pushbuffer empty, but we have more IB entries to read | 103 | // Current pushbuffer empty, but we have more IB entries to read |
| 96 | const CommandList& command_list{dma_pushbuffer.front()}; | 104 | const CommandList& command_list{dma_pushbuffer.front()}; |
diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h index 1097e5c49..14b23b1d7 100644 --- a/src/video_core/dma_pusher.h +++ b/src/video_core/dma_pusher.h | |||
| @@ -75,6 +75,8 @@ private: | |||
| 75 | 75 | ||
| 76 | GPU& gpu; | 76 | GPU& gpu; |
| 77 | 77 | ||
| 78 | std::vector<CommandHeader> command_headers; ///< Buffer for list of commands fetched at once | ||
| 79 | |||
| 78 | std::queue<CommandList> dma_pushbuffer; ///< Queue of command lists to be processed | 80 | std::queue<CommandList> dma_pushbuffer; ///< Queue of command lists to be processed |
| 79 | std::size_t dma_pushbuffer_subindex{}; ///< Index within a command list within the pushbuffer | 81 | std::size_t dma_pushbuffer_subindex{}; ///< Index within a command list within the pushbuffer |
| 80 | 82 | ||