summaryrefslogtreecommitdiff
path: root/src/video_core/gpu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/gpu.cpp')
-rw-r--r--src/video_core/gpu.cpp55
1 files changed, 50 insertions, 5 deletions
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 3b7572d61..b87fd873d 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -9,6 +9,7 @@
9#include "core/core_timing_util.h" 9#include "core/core_timing_util.h"
10#include "core/frontend/emu_window.h" 10#include "core/frontend/emu_window.h"
11#include "core/memory.h" 11#include "core/memory.h"
12#include "core/settings.h"
12#include "video_core/engines/fermi_2d.h" 13#include "video_core/engines/fermi_2d.h"
13#include "video_core/engines/kepler_compute.h" 14#include "video_core/engines/kepler_compute.h"
14#include "video_core/engines/kepler_memory.h" 15#include "video_core/engines/kepler_memory.h"
@@ -154,7 +155,10 @@ u64 GPU::GetTicks() const {
154 constexpr u64 gpu_ticks_den = 625; 155 constexpr u64 gpu_ticks_den = 625;
155 156
156 const u64 cpu_ticks = system.CoreTiming().GetTicks(); 157 const u64 cpu_ticks = system.CoreTiming().GetTicks();
157 const u64 nanoseconds = Core::Timing::CyclesToNs(cpu_ticks).count(); 158 u64 nanoseconds = Core::Timing::CyclesToNs(cpu_ticks).count();
159 if (Settings::values.use_fast_gpu_time) {
160 nanoseconds /= 256;
161 }
158 const u64 nanoseconds_num = nanoseconds / gpu_ticks_den; 162 const u64 nanoseconds_num = nanoseconds / gpu_ticks_den;
159 const u64 nanoseconds_rem = nanoseconds % gpu_ticks_den; 163 const u64 nanoseconds_rem = nanoseconds % gpu_ticks_den;
160 return nanoseconds_num * gpu_ticks_num + (nanoseconds_rem * gpu_ticks_num) / gpu_ticks_den; 164 return nanoseconds_num * gpu_ticks_num + (nanoseconds_rem * gpu_ticks_num) / gpu_ticks_den;
@@ -209,16 +213,32 @@ void GPU::CallMethod(const MethodCall& method_call) {
209 213
210 ASSERT(method_call.subchannel < bound_engines.size()); 214 ASSERT(method_call.subchannel < bound_engines.size());
211 215
212 if (ExecuteMethodOnEngine(method_call)) { 216 if (ExecuteMethodOnEngine(method_call.method)) {
213 CallEngineMethod(method_call); 217 CallEngineMethod(method_call);
214 } else { 218 } else {
215 CallPullerMethod(method_call); 219 CallPullerMethod(method_call);
216 } 220 }
217} 221}
218 222
219bool GPU::ExecuteMethodOnEngine(const MethodCall& method_call) { 223void GPU::CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
220 const auto method = static_cast<BufferMethods>(method_call.method); 224 u32 methods_pending) {
221 return method >= BufferMethods::NonPullerMethods; 225 LOG_TRACE(HW_GPU, "Processing method {:08X} on subchannel {}", method, subchannel);
226
227 ASSERT(subchannel < bound_engines.size());
228
229 if (ExecuteMethodOnEngine(method)) {
230 CallEngineMultiMethod(method, subchannel, base_start, amount, methods_pending);
231 } else {
232 for (std::size_t i = 0; i < amount; i++) {
233 CallPullerMethod(
234 {method, base_start[i], subchannel, methods_pending - static_cast<u32>(i)});
235 }
236 }
237}
238
239bool GPU::ExecuteMethodOnEngine(u32 method) {
240 const auto buffer_method = static_cast<BufferMethods>(method);
241 return buffer_method >= BufferMethods::NonPullerMethods;
222} 242}
223 243
224void GPU::CallPullerMethod(const MethodCall& method_call) { 244void GPU::CallPullerMethod(const MethodCall& method_call) {
@@ -298,6 +318,31 @@ void GPU::CallEngineMethod(const MethodCall& method_call) {
298 } 318 }
299} 319}
300 320
321void GPU::CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
322 u32 methods_pending) {
323 const EngineID engine = bound_engines[subchannel];
324
325 switch (engine) {
326 case EngineID::FERMI_TWOD_A:
327 fermi_2d->CallMultiMethod(method, base_start, amount, methods_pending);
328 break;
329 case EngineID::MAXWELL_B:
330 maxwell_3d->CallMultiMethod(method, base_start, amount, methods_pending);
331 break;
332 case EngineID::KEPLER_COMPUTE_B:
333 kepler_compute->CallMultiMethod(method, base_start, amount, methods_pending);
334 break;
335 case EngineID::MAXWELL_DMA_COPY_A:
336 maxwell_dma->CallMultiMethod(method, base_start, amount, methods_pending);
337 break;
338 case EngineID::KEPLER_INLINE_TO_MEMORY_B:
339 kepler_memory->CallMultiMethod(method, base_start, amount, methods_pending);
340 break;
341 default:
342 UNIMPLEMENTED_MSG("Unimplemented engine");
343 }
344}
345
301void GPU::ProcessBindMethod(const MethodCall& method_call) { 346void GPU::ProcessBindMethod(const MethodCall& method_call) {
302 // Bind the current subchannel to the desired engine id. 347 // Bind the current subchannel to the desired engine id.
303 LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel, 348 LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel,