summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/dma_pusher.cpp57
-rw-r--r--src/video_core/dma_pusher.h5
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() {
33} 33}
34 34
35bool DmaPusher::Step() { 35bool 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 const CommandHeader command_header{Memory::Read32(*address)}; 41 const CommandList& command_list{dma_pushbuffer.front()};
42 const CommandListHeader& command_list_header{command_list[dma_pushbuffer_subindex++]};
43 GPUVAddr dma_get = command_list_header.addr;
44 GPUVAddr dma_put = dma_get + command_list_header.size * sizeof(u32);
45 bool non_main = command_list_header.is_non_main;
42 46
43 dma_get += sizeof(u32); 47 if (dma_pushbuffer_subindex >= command_list.size()) {
48 // We've gone through the current list, remove it from the queue
49 dma_pushbuffer.pop();
50 dma_pushbuffer_subindex = 0;
51 }
44 52
45 if (!non_main) { 53 if (command_list_header.size == 0) {
46 dma_mget = dma_get; 54 return true;
47 } 55 }
56
57 // Push buffer non-empty, read a word
58 const auto address = gpu.MemoryManager().GpuToCpuAddress(dma_get);
59 ASSERT_MSG(address, "Invalid GPU address");
60
61 command_headers.resize(command_list_header.size);
62
63 Memory::ReadBlock(*address, command_headers.data(), command_list_header.size * sizeof(u32));
64
65 for (const CommandHeader& command_header : command_headers) {
48 66
49 // now, see if we're in the middle of a command 67 // now, see if we're in the middle of a command
50 if (dma_state.length_pending) { 68 if (dma_state.length_pending) {
@@ -91,22 +109,11 @@ bool DmaPusher::Step() {
91 break; 109 break;
92 } 110 }
93 } 111 }
94 } else if (ib_enable && !dma_pushbuffer.empty()) { 112 }
95 // Current pushbuffer empty, but we have more IB entries to read 113
96 const CommandList& command_list{dma_pushbuffer.front()}; 114 if (!non_main) {
97 const CommandListHeader& command_list_header{command_list[dma_pushbuffer_subindex++]}; 115 // TODO (degasus): This is dead code, as dma_mget is never read.
98 dma_get = command_list_header.addr; 116 dma_mget = dma_put;
99 dma_put = dma_get + command_list_header.size * sizeof(u32);
100 non_main = command_list_header.is_non_main;
101
102 if (dma_pushbuffer_subindex >= command_list.size()) {
103 // We've gone through the current list, remove it from the queue
104 dma_pushbuffer.pop();
105 dma_pushbuffer_subindex = 0;
106 }
107 } else {
108 // Otherwise, pushbuffer empty and IB empty or nonexistent - nothing to do
109 return {};
110 } 117 }
111 118
112 return true; 119 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:
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
@@ -89,11 +91,8 @@ private:
89 DmaState dma_state{}; 91 DmaState dma_state{};
90 bool dma_increment_once{}; 92 bool dma_increment_once{};
91 93
92 GPUVAddr dma_put{}; ///< pushbuffer current end address
93 GPUVAddr dma_get{}; ///< pushbuffer current read address
94 GPUVAddr dma_mget{}; ///< main pushbuffer last read address 94 GPUVAddr dma_mget{}; ///< main pushbuffer last read address
95 bool ib_enable{true}; ///< IB mode enabled 95 bool ib_enable{true}; ///< IB mode enabled
96 bool non_main{}; ///< non-main pushbuffer active
97}; 96};
98 97
99} // namespace Tegra 98} // namespace Tegra