aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/engines/kepler_compute.cpp
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 08:04:42 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 20:49:47 -0400
commit6cefcce15f821cd0e65459173cf217bb7e622f43 (patch)
tree293629f633fed276a5fee9d658d2ab0bfa807da5 /src/video_core/engines/kepler_compute.cpp
parent15eef40dd12c2b751d5b1cac57dd8f3602e2d133 (diff)
kepler_compute: store plain native register writes directly
Most native compute register writes (QMD fields its macros replay for thousands of dispatches a second) only store the value; they went through ProcessNativeMethod's macro, QMD, upload and semaphore checks. CallMethod now stores them through a table of plain methods. ProcessNativeMethod's own time 2.2% -> 1.6% of the GPU thread.
Diffstat (limited to 'src/video_core/engines/kepler_compute.cpp')
-rw-r--r--src/video_core/engines/kepler_compute.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp
index 7792bc9b5d..786acc04de 100644
--- a/src/video_core/engines/kepler_compute.cpp
+++ b/src/video_core/engines/kepler_compute.cpp
@@ -43,6 +43,20 @@ KeplerCompute::KeplerCompute(MemoryManager& memory_manager_)
execution_mask[KEPLER_COMPUTE_REG_INDEX(exec_upload)] = true;
execution_mask[KEPLER_COMPUTE_REG_INDEX(data_upload)] = true;
execution_mask[KEPLER_COMPUTE_REG_INDEX(launch)] = true;
+ // Everything ProcessNativeMethod acts on besides storing the value; the QMD and 0x5a
+ // trace range too while native draw diagnostics trace it.
+ native_plain_methods.set();
+ for (const u32 method : {0x45U, 0x46U, 0x47U, 0x48U, 0xaeU, 0xafU, 0xb0U, 0x107U, 0x6c3U,
+ static_cast<u32>(KEPLER_COMPUTE_REG_INDEX(exec_upload)),
+ static_cast<u32>(KEPLER_COMPUTE_REG_INDEX(data_upload))}) {
+ native_plain_methods[method] = false;
+ }
+ if (std::getenv("EDEN_NATIVE_DRAW_DIAGNOSTICS") != nullptr) {
+ native_plain_methods[0x5a] = false;
+ for (u32 method = 0xc6; method <= 0x108; ++method) {
+ native_plain_methods[method] = false;
+ }
+ }
}
KeplerCompute::~KeplerCompute() = default;
@@ -390,7 +404,19 @@ bool KeplerCompute::ProcessNativeMethod(Core::System& system, u32 method, u32 ar
}
void KeplerCompute::CallMethod(Core::System& system, u32 method, u32 method_argument, bool is_last_call) {
- if (native_mode && ProcessNativeMethod(system, method, method_argument, is_last_call)) return;
+ if (native_mode) {
+ // Most of the compute class's register writes (QMD fields replayed by its macros for
+ // each of thousands of dispatches a second) only store the value: ~4% of title 1's GPU
+ // thread went through ProcessNativeMethod's checks for them.
+ if (method < native_plain_methods.size() && native_plain_methods[method]) {
+ native_registers[method] = method_argument;
+ if (method < Regs::NUM_REGS) {
+ regs.reg_array[method] = method_argument;
+ }
+ return;
+ }
+ if (ProcessNativeMethod(system, method, method_argument, is_last_call)) return;
+ }
if (method >= Regs::NUM_REGS) {
LOG_ERROR(HW_GPU, "Compute register out of range: {:#x}", method);
return;