diff options
| author | 2020-04-27 22:07:21 -0400 | |
|---|---|---|
| committer | 2020-04-27 22:07:21 -0400 | |
| commit | b87422a86f4dd3b59ef91c3ce37945865a6cfbef (patch) | |
| tree | f7a0231f8a226f2dc73ca84fe77aa066f8b912d4 | |
| parent | VideoCore/Engines: Refactor Engines CallMethod. (diff) | |
| download | yuzu-b87422a86f4dd3b59ef91c3ce37945865a6cfbef.tar.gz yuzu-b87422a86f4dd3b59ef91c3ce37945865a6cfbef.tar.xz yuzu-b87422a86f4dd3b59ef91c3ce37945865a6cfbef.zip | |
VideoCore/GPU: Delegate subchannel engines to the dma pusher.
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 20 | ||||
| -rw-r--r-- | src/video_core/dma_pusher.h | 11 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 22 |
3 files changed, 49 insertions, 4 deletions
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 16311f05e..bdc023d54 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp | |||
| @@ -27,6 +27,8 @@ void DmaPusher::DispatchCalls() { | |||
| 27 | 27 | ||
| 28 | dma_pushbuffer_subindex = 0; | 28 | dma_pushbuffer_subindex = 0; |
| 29 | 29 | ||
| 30 | dma_state.is_last_call = true; | ||
| 31 | |||
| 30 | while (system.IsPoweredOn()) { | 32 | while (system.IsPoweredOn()) { |
| 31 | if (!Step()) { | 33 | if (!Step()) { |
| 32 | break; | 34 | break; |
| @@ -82,9 +84,11 @@ bool DmaPusher::Step() { | |||
| 82 | index); | 84 | index); |
| 83 | CallMultiMethod(&command_header.argument, max_write); | 85 | CallMultiMethod(&command_header.argument, max_write); |
| 84 | dma_state.method_count -= max_write; | 86 | dma_state.method_count -= max_write; |
| 87 | dma_state.is_last_call = true; | ||
| 85 | index += max_write; | 88 | index += max_write; |
| 86 | continue; | 89 | continue; |
| 87 | } else { | 90 | } else { |
| 91 | dma_state.is_last_call = dma_state.method_count <= 1; | ||
| 88 | CallMethod(command_header.argument); | 92 | CallMethod(command_header.argument); |
| 89 | } | 93 | } |
| 90 | 94 | ||
| @@ -144,12 +148,22 @@ void DmaPusher::SetState(const CommandHeader& command_header) { | |||
| 144 | } | 148 | } |
| 145 | 149 | ||
| 146 | void DmaPusher::CallMethod(u32 argument) const { | 150 | void DmaPusher::CallMethod(u32 argument) const { |
| 147 | gpu.CallMethod({dma_state.method, argument, dma_state.subchannel, dma_state.method_count}); | 151 | if (dma_state.method < non_puller_methods) { |
| 152 | gpu.CallMethod({dma_state.method, argument, dma_state.subchannel, dma_state.method_count}); | ||
| 153 | } else { | ||
| 154 | subchannels[dma_state.subchannel]->CallMethod(dma_state.method, argument, | ||
| 155 | dma_state.is_last_call); | ||
| 156 | } | ||
| 148 | } | 157 | } |
| 149 | 158 | ||
| 150 | void DmaPusher::CallMultiMethod(const u32* base_start, u32 num_methods) const { | 159 | void DmaPusher::CallMultiMethod(const u32* base_start, u32 num_methods) const { |
| 151 | gpu.CallMultiMethod(dma_state.method, dma_state.subchannel, base_start, num_methods, | 160 | if (dma_state.method < non_puller_methods) { |
| 152 | dma_state.method_count); | 161 | gpu.CallMultiMethod(dma_state.method, dma_state.subchannel, base_start, num_methods, |
| 162 | dma_state.method_count); | ||
| 163 | } else { | ||
| 164 | subchannels[dma_state.subchannel]->CallMultiMethod(dma_state.method, base_start, | ||
| 165 | num_methods, dma_state.method_count); | ||
| 166 | } | ||
| 153 | } | 167 | } |
| 154 | 168 | ||
| 155 | } // namespace Tegra | 169 | } // namespace Tegra |
diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h index 6cef71306..e8b714e94 100644 --- a/src/video_core/dma_pusher.h +++ b/src/video_core/dma_pusher.h | |||
| @@ -4,11 +4,13 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 7 | #include <vector> | 8 | #include <vector> |
| 8 | #include <queue> | 9 | #include <queue> |
| 9 | 10 | ||
| 10 | #include "common/bit_field.h" | 11 | #include "common/bit_field.h" |
| 11 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 13 | #include "video_core/engines/engine_interface.h" | ||
| 12 | 14 | ||
| 13 | namespace Core { | 15 | namespace Core { |
| 14 | class System; | 16 | class System; |
| @@ -69,7 +71,13 @@ public: | |||
| 69 | 71 | ||
| 70 | void DispatchCalls(); | 72 | void DispatchCalls(); |
| 71 | 73 | ||
| 74 | void BindSubchannel(Tegra::Engines::EngineInterface* engine, u32 subchannel_id) { | ||
| 75 | subchannels[subchannel_id] = engine; | ||
| 76 | } | ||
| 77 | |||
| 72 | private: | 78 | private: |
| 79 | static constexpr u32 non_puller_methods = 0x40; | ||
| 80 | static constexpr u32 max_subchannels = 8; | ||
| 73 | bool Step(); | 81 | bool Step(); |
| 74 | 82 | ||
| 75 | void SetState(const CommandHeader& command_header); | 83 | void SetState(const CommandHeader& command_header); |
| @@ -88,6 +96,7 @@ private: | |||
| 88 | u32 method_count; ///< Current method count | 96 | u32 method_count; ///< Current method count |
| 89 | u32 length_pending; ///< Large NI command length pending | 97 | u32 length_pending; ///< Large NI command length pending |
| 90 | bool non_incrementing; ///< Current command's NI flag | 98 | bool non_incrementing; ///< Current command's NI flag |
| 99 | bool is_last_call; | ||
| 91 | }; | 100 | }; |
| 92 | 101 | ||
| 93 | DmaState dma_state{}; | 102 | DmaState dma_state{}; |
| @@ -96,6 +105,8 @@ private: | |||
| 96 | GPUVAddr dma_mget{}; ///< main pushbuffer last read address | 105 | GPUVAddr dma_mget{}; ///< main pushbuffer last read address |
| 97 | bool ib_enable{true}; ///< IB mode enabled | 106 | bool ib_enable{true}; ///< IB mode enabled |
| 98 | 107 | ||
| 108 | std::array<Tegra::Engines::EngineInterface*, max_subchannels> subchannels{}; | ||
| 109 | |||
| 99 | GPU& gpu; | 110 | GPU& gpu; |
| 100 | Core::System& system; | 111 | Core::System& system; |
| 101 | }; | 112 | }; |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 4868437c1..f10d69fd5 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -347,7 +347,27 @@ void GPU::ProcessBindMethod(const MethodCall& method_call) { | |||
| 347 | // Bind the current subchannel to the desired engine id. | 347 | // Bind the current subchannel to the desired engine id. |
| 348 | LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel, | 348 | LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel, |
| 349 | method_call.argument); | 349 | method_call.argument); |
| 350 | bound_engines[method_call.subchannel] = static_cast<EngineID>(method_call.argument); | 350 | auto engine_id = static_cast<EngineID>(method_call.argument); |
| 351 | bound_engines[method_call.subchannel] = static_cast<EngineID>(engine_id); | ||
| 352 | switch (engine_id) { | ||
| 353 | case EngineID::FERMI_TWOD_A: | ||
| 354 | dma_pusher->BindSubchannel(fermi_2d.get(), method_call.subchannel); | ||
| 355 | break; | ||
| 356 | case EngineID::MAXWELL_B: | ||
| 357 | dma_pusher->BindSubchannel(maxwell_3d.get(), method_call.subchannel); | ||
| 358 | break; | ||
| 359 | case EngineID::KEPLER_COMPUTE_B: | ||
| 360 | dma_pusher->BindSubchannel(kepler_compute.get(), method_call.subchannel); | ||
| 361 | break; | ||
| 362 | case EngineID::MAXWELL_DMA_COPY_A: | ||
| 363 | dma_pusher->BindSubchannel(maxwell_dma.get(), method_call.subchannel); | ||
| 364 | break; | ||
| 365 | case EngineID::KEPLER_INLINE_TO_MEMORY_B: | ||
| 366 | dma_pusher->BindSubchannel(kepler_memory.get(), method_call.subchannel); | ||
| 367 | break; | ||
| 368 | default: | ||
| 369 | UNIMPLEMENTED_MSG("Unimplemented engine"); | ||
| 370 | } | ||
| 351 | } | 371 | } |
| 352 | 372 | ||
| 353 | void GPU::ProcessSemaphoreTriggerMethod() { | 373 | void GPU::ProcessSemaphoreTriggerMethod() { |