diff options
| author | 2020-04-27 00:18:46 -0400 | |
|---|---|---|
| committer | 2020-04-27 00:18:46 -0400 | |
| commit | 6c7d8073be9ab0ce92d346742989800895beeffe (patch) | |
| tree | 298da9383d7f883102643f0ab146dda72d9f5358 /src/video_core/gpu.cpp | |
| parent | Merge pull request #3795 from vitor-k/fix-folder (diff) | |
| parent | Clang Format. (diff) | |
| download | yuzu-6c7d8073be9ab0ce92d346742989800895beeffe.tar.gz yuzu-6c7d8073be9ab0ce92d346742989800895beeffe.tar.xz yuzu-6c7d8073be9ab0ce92d346742989800895beeffe.zip | |
Merge pull request #3742 from FernandoS27/command-list
Optimize GPU Command Lists and Introduce Fast GPU Time Option
Diffstat (limited to 'src/video_core/gpu.cpp')
| -rw-r--r-- | src/video_core/gpu.cpp | 55 |
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 | ||
| 219 | bool GPU::ExecuteMethodOnEngine(const MethodCall& method_call) { | 223 | void 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 | |||
| 239 | bool GPU::ExecuteMethodOnEngine(u32 method) { | ||
| 240 | const auto buffer_method = static_cast<BufferMethods>(method); | ||
| 241 | return buffer_method >= BufferMethods::NonPullerMethods; | ||
| 222 | } | 242 | } |
| 223 | 243 | ||
| 224 | void GPU::CallPullerMethod(const MethodCall& method_call) { | 244 | void GPU::CallPullerMethod(const MethodCall& method_call) { |
| @@ -298,6 +318,31 @@ void GPU::CallEngineMethod(const MethodCall& method_call) { | |||
| 298 | } | 318 | } |
| 299 | } | 319 | } |
| 300 | 320 | ||
| 321 | void 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 | |||
| 301 | void GPU::ProcessBindMethod(const MethodCall& method_call) { | 346 | void 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, |