summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/dma_pusher.cpp20
-rw-r--r--src/video_core/dma_pusher.h11
-rw-r--r--src/video_core/gpu.cpp22
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
146void DmaPusher::CallMethod(u32 argument) const { 150void 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
150void DmaPusher::CallMultiMethod(const u32* base_start, u32 num_methods) const { 159void 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
13namespace Core { 15namespace Core {
14class System; 16class 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
72private: 78private:
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
353void GPU::ProcessSemaphoreTriggerMethod() { 373void GPU::ProcessSemaphoreTriggerMethod() {