summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/stream.cpp7
-rw-r--r--src/audio_core/stream.h22
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp6
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp4
-rw-r--r--src/core/core.cpp6
-rw-r--r--src/core/core_cpu.cpp6
-rw-r--r--src/core/core_timing.cpp4
-rw-r--r--src/core/core_timing.h4
-rw-r--r--src/core/core_timing_util.cpp4
-rw-r--r--src/core/core_timing_util.h4
-rw-r--r--src/core/hle/kernel/kernel.cpp6
-rw-r--r--src/core/hle/kernel/kernel.h4
-rw-r--r--src/core/hle/kernel/scheduler.cpp2
-rw-r--r--src/core/hle/kernel/svc.cpp8
-rw-r--r--src/core/hle/kernel/thread.cpp13
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/mouse.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/stubbed.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp4
-rw-r--r--src/core/hle/service/hid/controllers/xpad.cpp2
-rw-r--r--src/core/hle/service/hid/hid.cpp19
-rw-r--r--src/core/hle/service/hid/hid.h4
-rw-r--r--src/core/hle/service/hid/irs.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp2
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.h4
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp10
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h6
-rw-r--r--src/core/hle/service/time/time.cpp6
-rw-r--r--src/tests/core/core_timing.cpp169
-rw-r--r--src/video_core/CMakeLists.txt4
-rw-r--r--src/video_core/engines/kepler_compute.cpp34
-rw-r--r--src/video_core/engines/kepler_compute.h (renamed from src/video_core/engines/maxwell_compute.h)31
-rw-r--r--src/video_core/engines/maxwell_3d.cpp2
-rw-r--r--src/video_core/engines/maxwell_compute.cpp28
-rw-r--r--src/video_core/engines/shader_bytecode.h2
-rw-r--r--src/video_core/gpu.cpp10
-rw-r--r--src/video_core/gpu.h6
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp97
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp6
-rw-r--r--src/video_core/shader/decode/arithmetic_integer.cpp4
-rw-r--r--src/video_core/shader/decode/conversion.cpp6
-rw-r--r--src/video_core/shader/decode/memory.cpp157
-rw-r--r--src/video_core/shader/shader_ir.h22
46 files changed, 362 insertions, 387 deletions
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index 4ce2d374e..8ab5649df 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -37,7 +37,7 @@ Stream::Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callbac
37 : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)}, 37 : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
38 sink_stream{sink_stream}, name{std::move(name_)} { 38 sink_stream{sink_stream}, name{std::move(name_)} {
39 39
40 release_event = CoreTiming::RegisterEvent( 40 release_event = Core::Timing::RegisterEvent(
41 name, [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); }); 41 name, [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); });
42} 42}
43 43
@@ -57,7 +57,7 @@ Stream::State Stream::GetState() const {
57 57
58s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const { 58s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
59 const std::size_t num_samples{buffer.GetSamples().size() / GetNumChannels()}; 59 const std::size_t num_samples{buffer.GetSamples().size() / GetNumChannels()};
60 return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate); 60 return Core::Timing::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
61} 61}
62 62
63static void VolumeAdjustSamples(std::vector<s16>& samples) { 63static void VolumeAdjustSamples(std::vector<s16>& samples) {
@@ -99,7 +99,8 @@ void Stream::PlayNextBuffer() {
99 99
100 sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); 100 sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples());
101 101
102 CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {}); 102 Core::Timing::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event,
103 {});
103} 104}
104 105
105void Stream::ReleaseActiveBuffer() { 106void Stream::ReleaseActiveBuffer() {
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h
index aebfeb51d..caa775544 100644
--- a/src/audio_core/stream.h
+++ b/src/audio_core/stream.h
@@ -13,7 +13,7 @@
13#include "audio_core/buffer.h" 13#include "audio_core/buffer.h"
14#include "common/common_types.h" 14#include "common/common_types.h"
15 15
16namespace CoreTiming { 16namespace Core::Timing {
17struct EventType; 17struct EventType;
18} 18}
19 19
@@ -91,16 +91,16 @@ private:
91 /// Gets the number of core cycles when the specified buffer will be released 91 /// Gets the number of core cycles when the specified buffer will be released
92 s64 GetBufferReleaseCycles(const Buffer& buffer) const; 92 s64 GetBufferReleaseCycles(const Buffer& buffer) const;
93 93
94 u32 sample_rate; ///< Sample rate of the stream 94 u32 sample_rate; ///< Sample rate of the stream
95 Format format; ///< Format of the stream 95 Format format; ///< Format of the stream
96 ReleaseCallback release_callback; ///< Buffer release callback for the stream 96 ReleaseCallback release_callback; ///< Buffer release callback for the stream
97 State state{State::Stopped}; ///< Playback state of the stream 97 State state{State::Stopped}; ///< Playback state of the stream
98 CoreTiming::EventType* release_event{}; ///< Core timing release event for the stream 98 Core::Timing::EventType* release_event{}; ///< Core timing release event for the stream
99 BufferPtr active_buffer; ///< Actively playing buffer in the stream 99 BufferPtr active_buffer; ///< Actively playing buffer in the stream
100 std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream 100 std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream
101 std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream 101 std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream
102 SinkStream& sink_stream; ///< Output sink for the stream 102 SinkStream& sink_stream; ///< Output sink for the stream
103 std::string name; ///< Name of the stream, must be unique 103 std::string name; ///< Name of the stream, must be unique
104}; 104};
105 105
106using StreamPtr = std::shared_ptr<Stream>; 106using StreamPtr = std::shared_ptr<Stream>;
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index afbda8d8b..f28951f8a 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -112,14 +112,14 @@ public:
112 // Always execute at least one tick. 112 // Always execute at least one tick.
113 amortized_ticks = std::max<u64>(amortized_ticks, 1); 113 amortized_ticks = std::max<u64>(amortized_ticks, 1);
114 114
115 CoreTiming::AddTicks(amortized_ticks); 115 Timing::AddTicks(amortized_ticks);
116 num_interpreted_instructions = 0; 116 num_interpreted_instructions = 0;
117 } 117 }
118 u64 GetTicksRemaining() override { 118 u64 GetTicksRemaining() override {
119 return std::max(CoreTiming::GetDowncount(), 0); 119 return std::max(Timing::GetDowncount(), 0);
120 } 120 }
121 u64 GetCNTPCT() override { 121 u64 GetCNTPCT() override {
122 return CoreTiming::GetTicks(); 122 return Timing::GetTicks();
123 } 123 }
124 124
125 ARM_Dynarmic& parent; 125 ARM_Dynarmic& parent;
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index c455c81fb..c36c15c02 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -177,7 +177,7 @@ void ARM_Unicorn::Run() {
177 if (GDBStub::IsServerEnabled()) { 177 if (GDBStub::IsServerEnabled()) {
178 ExecuteInstructions(std::max(4000000, 0)); 178 ExecuteInstructions(std::max(4000000, 0));
179 } else { 179 } else {
180 ExecuteInstructions(std::max(CoreTiming::GetDowncount(), 0)); 180 ExecuteInstructions(std::max(Timing::GetDowncount(), 0));
181 } 181 }
182} 182}
183 183
@@ -190,7 +190,7 @@ MICROPROFILE_DEFINE(ARM_Jit_Unicorn, "ARM JIT", "Unicorn", MP_RGB(255, 64, 64));
190void ARM_Unicorn::ExecuteInstructions(int num_instructions) { 190void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
191 MICROPROFILE_SCOPE(ARM_Jit_Unicorn); 191 MICROPROFILE_SCOPE(ARM_Jit_Unicorn);
192 CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions)); 192 CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions));
193 CoreTiming::AddTicks(num_instructions); 193 Timing::AddTicks(num_instructions);
194 if (GDBStub::IsServerEnabled()) { 194 if (GDBStub::IsServerEnabled()) {
195 if (last_bkpt_hit) { 195 if (last_bkpt_hit) {
196 uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address); 196 uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address);
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 1dd576c26..4d9d21ee4 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -94,7 +94,7 @@ struct System::Impl {
94 ResultStatus Init(System& system, Frontend::EmuWindow& emu_window) { 94 ResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
95 LOG_DEBUG(HW_Memory, "initialized OK"); 95 LOG_DEBUG(HW_Memory, "initialized OK");
96 96
97 CoreTiming::Init(); 97 Timing::Init();
98 kernel.Initialize(); 98 kernel.Initialize();
99 99
100 const auto current_time = std::chrono::duration_cast<std::chrono::seconds>( 100 const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
@@ -205,7 +205,7 @@ struct System::Impl {
205 205
206 // Shutdown kernel and core timing 206 // Shutdown kernel and core timing
207 kernel.Shutdown(); 207 kernel.Shutdown();
208 CoreTiming::Shutdown(); 208 Timing::Shutdown();
209 209
210 // Close app loader 210 // Close app loader
211 app_loader.reset(); 211 app_loader.reset();
@@ -232,7 +232,7 @@ struct System::Impl {
232 } 232 }
233 233
234 PerfStatsResults GetAndResetPerfStats() { 234 PerfStatsResults GetAndResetPerfStats() {
235 return perf_stats.GetAndResetStats(CoreTiming::GetGlobalTimeUs()); 235 return perf_stats.GetAndResetStats(Timing::GetGlobalTimeUs());
236 } 236 }
237 237
238 Kernel::KernelCore kernel; 238 Kernel::KernelCore kernel;
diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp
index fffda8a99..452366250 100644
--- a/src/core/core_cpu.cpp
+++ b/src/core/core_cpu.cpp
@@ -93,14 +93,14 @@ void Cpu::RunLoop(bool tight_loop) {
93 93
94 if (IsMainCore()) { 94 if (IsMainCore()) {
95 // TODO(Subv): Only let CoreTiming idle if all 4 cores are idling. 95 // TODO(Subv): Only let CoreTiming idle if all 4 cores are idling.
96 CoreTiming::Idle(); 96 Timing::Idle();
97 CoreTiming::Advance(); 97 Timing::Advance();
98 } 98 }
99 99
100 PrepareReschedule(); 100 PrepareReschedule();
101 } else { 101 } else {
102 if (IsMainCore()) { 102 if (IsMainCore()) {
103 CoreTiming::Advance(); 103 Timing::Advance();
104 } 104 }
105 105
106 if (tight_loop) { 106 if (tight_loop) {
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 7953c8720..2b7ca9766 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -15,7 +15,7 @@
15#include "common/threadsafe_queue.h" 15#include "common/threadsafe_queue.h"
16#include "core/core_timing_util.h" 16#include "core/core_timing_util.h"
17 17
18namespace CoreTiming { 18namespace Core::Timing {
19 19
20static s64 global_timer; 20static s64 global_timer;
21static int slice_length; 21static int slice_length;
@@ -242,4 +242,4 @@ int GetDowncount() {
242 return downcount; 242 return downcount;
243} 243}
244 244
245} // namespace CoreTiming 245} // namespace Core::Timing
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 9ed757bd7..093989d4c 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -22,7 +22,7 @@
22#include <string> 22#include <string>
23#include "common/common_types.h" 23#include "common/common_types.h"
24 24
25namespace CoreTiming { 25namespace Core::Timing {
26 26
27struct EventType; 27struct EventType;
28 28
@@ -92,4 +92,4 @@ std::chrono::microseconds GetGlobalTimeUs();
92 92
93int GetDowncount(); 93int GetDowncount();
94 94
95} // namespace CoreTiming 95} // namespace Core::Timing
diff --git a/src/core/core_timing_util.cpp b/src/core/core_timing_util.cpp
index 73dea4edb..88ff70233 100644
--- a/src/core/core_timing_util.cpp
+++ b/src/core/core_timing_util.cpp
@@ -8,7 +8,7 @@
8#include <limits> 8#include <limits>
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10 10
11namespace CoreTiming { 11namespace Core::Timing {
12 12
13constexpr u64 MAX_VALUE_TO_MULTIPLY = std::numeric_limits<s64>::max() / BASE_CLOCK_RATE; 13constexpr u64 MAX_VALUE_TO_MULTIPLY = std::numeric_limits<s64>::max() / BASE_CLOCK_RATE;
14 14
@@ -60,4 +60,4 @@ s64 nsToCycles(u64 ns) {
60 return (BASE_CLOCK_RATE * static_cast<s64>(ns)) / 1000000000; 60 return (BASE_CLOCK_RATE * static_cast<s64>(ns)) / 1000000000;
61} 61}
62 62
63} // namespace CoreTiming 63} // namespace Core::Timing
diff --git a/src/core/core_timing_util.h b/src/core/core_timing_util.h
index 5c3718782..513cfac1b 100644
--- a/src/core/core_timing_util.h
+++ b/src/core/core_timing_util.h
@@ -6,7 +6,7 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8 8
9namespace CoreTiming { 9namespace Core::Timing {
10 10
11// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz 11// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz
12// The exact value used is of course unverified. 12// The exact value used is of course unverified.
@@ -61,4 +61,4 @@ inline u64 cyclesToMs(s64 cycles) {
61 return cycles * 1000 / BASE_CLOCK_RATE; 61 return cycles * 1000 / BASE_CLOCK_RATE;
62} 62}
63 63
64} // namespace CoreTiming 64} // namespace Core::Timing
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 7a524ce5a..3721ae8fe 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -124,7 +124,7 @@ struct KernelCore::Impl {
124 124
125 void InitializeThreads() { 125 void InitializeThreads() {
126 thread_wakeup_event_type = 126 thread_wakeup_event_type =
127 CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback); 127 Core::Timing::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
128 } 128 }
129 129
130 std::atomic<u32> next_object_id{0}; 130 std::atomic<u32> next_object_id{0};
@@ -137,7 +137,7 @@ struct KernelCore::Impl {
137 137
138 SharedPtr<ResourceLimit> system_resource_limit; 138 SharedPtr<ResourceLimit> system_resource_limit;
139 139
140 CoreTiming::EventType* thread_wakeup_event_type = nullptr; 140 Core::Timing::EventType* thread_wakeup_event_type = nullptr;
141 // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, 141 // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future,
142 // allowing us to simply use a pool index or similar. 142 // allowing us to simply use a pool index or similar.
143 Kernel::HandleTable thread_wakeup_callback_handle_table; 143 Kernel::HandleTable thread_wakeup_callback_handle_table;
@@ -213,7 +213,7 @@ u64 KernelCore::CreateNewProcessID() {
213 return impl->next_process_id++; 213 return impl->next_process_id++;
214} 214}
215 215
216CoreTiming::EventType* KernelCore::ThreadWakeupCallbackEventType() const { 216Core::Timing::EventType* KernelCore::ThreadWakeupCallbackEventType() const {
217 return impl->thread_wakeup_event_type; 217 return impl->thread_wakeup_event_type;
218} 218}
219 219
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index c643a6401..7406f107e 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -11,7 +11,7 @@
11template <typename T> 11template <typename T>
12class ResultVal; 12class ResultVal;
13 13
14namespace CoreTiming { 14namespace Core::Timing {
15struct EventType; 15struct EventType;
16} 16}
17 17
@@ -89,7 +89,7 @@ private:
89 u64 CreateNewThreadID(); 89 u64 CreateNewThreadID();
90 90
91 /// Retrieves the event type used for thread wakeup callbacks. 91 /// Retrieves the event type used for thread wakeup callbacks.
92 CoreTiming::EventType* ThreadWakeupCallbackEventType() const; 92 Core::Timing::EventType* ThreadWakeupCallbackEventType() const;
93 93
94 /// Provides a reference to the thread wakeup callback handle table. 94 /// Provides a reference to the thread wakeup callback handle table.
95 Kernel::HandleTable& ThreadWakeupCallbackHandleTable(); 95 Kernel::HandleTable& ThreadWakeupCallbackHandleTable();
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index df4d6cf0a..9e2517e1b 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -111,7 +111,7 @@ void Scheduler::SwitchContext(Thread* new_thread) {
111 111
112void Scheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) { 112void Scheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) {
113 const u64 prev_switch_ticks = last_context_switch_time; 113 const u64 prev_switch_ticks = last_context_switch_time;
114 const u64 most_recent_switch_ticks = CoreTiming::GetTicks(); 114 const u64 most_recent_switch_ticks = Core::Timing::GetTicks();
115 const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks; 115 const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks;
116 116
117 if (thread != nullptr) { 117 if (thread != nullptr) {
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 7cfecb68c..5f040f79f 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -927,9 +927,9 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
927 if (same_thread && info_sub_id == 0xFFFFFFFFFFFFFFFF) { 927 if (same_thread && info_sub_id == 0xFFFFFFFFFFFFFFFF) {
928 const u64 thread_ticks = current_thread->GetTotalCPUTimeTicks(); 928 const u64 thread_ticks = current_thread->GetTotalCPUTimeTicks();
929 929
930 out_ticks = thread_ticks + (CoreTiming::GetTicks() - prev_ctx_ticks); 930 out_ticks = thread_ticks + (Core::Timing::GetTicks() - prev_ctx_ticks);
931 } else if (same_thread && info_sub_id == system.CurrentCoreIndex()) { 931 } else if (same_thread && info_sub_id == system.CurrentCoreIndex()) {
932 out_ticks = CoreTiming::GetTicks() - prev_ctx_ticks; 932 out_ticks = Core::Timing::GetTicks() - prev_ctx_ticks;
933 } 933 }
934 934
935 *result = out_ticks; 935 *result = out_ticks;
@@ -1546,10 +1546,10 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to
1546static u64 GetSystemTick() { 1546static u64 GetSystemTick() {
1547 LOG_TRACE(Kernel_SVC, "called"); 1547 LOG_TRACE(Kernel_SVC, "called");
1548 1548
1549 const u64 result{CoreTiming::GetTicks()}; 1549 const u64 result{Core::Timing::GetTicks()};
1550 1550
1551 // Advance time to defeat dumb games that busy-wait for the frame to end. 1551 // Advance time to defeat dumb games that busy-wait for the frame to end.
1552 CoreTiming::AddTicks(400); 1552 Core::Timing::AddTicks(400);
1553 1553
1554 return result; 1554 return result;
1555} 1555}
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index d3984dfc4..7881c2b90 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -43,7 +43,7 @@ Thread::~Thread() = default;
43 43
44void Thread::Stop() { 44void Thread::Stop() {
45 // Cancel any outstanding wakeup events for this thread 45 // Cancel any outstanding wakeup events for this thread
46 CoreTiming::UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), callback_handle); 46 Core::Timing::UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), callback_handle);
47 kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle); 47 kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle);
48 callback_handle = 0; 48 callback_handle = 0;
49 49
@@ -85,12 +85,13 @@ void Thread::WakeAfterDelay(s64 nanoseconds) {
85 85
86 // This function might be called from any thread so we have to be cautious and use the 86 // This function might be called from any thread so we have to be cautious and use the
87 // thread-safe version of ScheduleEvent. 87 // thread-safe version of ScheduleEvent.
88 CoreTiming::ScheduleEventThreadsafe(CoreTiming::nsToCycles(nanoseconds), 88 Core::Timing::ScheduleEventThreadsafe(Core::Timing::nsToCycles(nanoseconds),
89 kernel.ThreadWakeupCallbackEventType(), callback_handle); 89 kernel.ThreadWakeupCallbackEventType(), callback_handle);
90} 90}
91 91
92void Thread::CancelWakeupTimer() { 92void Thread::CancelWakeupTimer() {
93 CoreTiming::UnscheduleEventThreadsafe(kernel.ThreadWakeupCallbackEventType(), callback_handle); 93 Core::Timing::UnscheduleEventThreadsafe(kernel.ThreadWakeupCallbackEventType(),
94 callback_handle);
94} 95}
95 96
96static std::optional<s32> GetNextProcessorId(u64 mask) { 97static std::optional<s32> GetNextProcessorId(u64 mask) {
@@ -197,7 +198,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
197 thread->stack_top = stack_top; 198 thread->stack_top = stack_top;
198 thread->tpidr_el0 = 0; 199 thread->tpidr_el0 = 0;
199 thread->nominal_priority = thread->current_priority = priority; 200 thread->nominal_priority = thread->current_priority = priority;
200 thread->last_running_ticks = CoreTiming::GetTicks(); 201 thread->last_running_ticks = Core::Timing::GetTicks();
201 thread->processor_id = processor_id; 202 thread->processor_id = processor_id;
202 thread->ideal_core = processor_id; 203 thread->ideal_core = processor_id;
203 thread->affinity_mask = 1ULL << processor_id; 204 thread->affinity_mask = 1ULL << processor_id;
@@ -257,7 +258,7 @@ void Thread::SetStatus(ThreadStatus new_status) {
257 } 258 }
258 259
259 if (status == ThreadStatus::Running) { 260 if (status == ThreadStatus::Running) {
260 last_running_ticks = CoreTiming::GetTicks(); 261 last_running_ticks = Core::Timing::GetTicks();
261 } 262 }
262 263
263 status = new_status; 264 status = new_status;
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp
index c22357d8c..b264c9503 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/core/hle/service/hid/controllers/debug_pad.cpp
@@ -22,7 +22,7 @@ void Controller_DebugPad::OnInit() {}
22void Controller_DebugPad::OnRelease() {} 22void Controller_DebugPad::OnRelease() {}
23 23
24void Controller_DebugPad::OnUpdate(u8* data, std::size_t size) { 24void Controller_DebugPad::OnUpdate(u8* data, std::size_t size) {
25 shared_memory.header.timestamp = CoreTiming::GetTicks(); 25 shared_memory.header.timestamp = Core::Timing::GetTicks();
26 shared_memory.header.total_entry_count = 17; 26 shared_memory.header.total_entry_count = 17;
27 27
28 if (!IsControllerActivated()) { 28 if (!IsControllerActivated()) {
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
index 898572277..6d21f1a7d 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -18,7 +18,7 @@ void Controller_Gesture::OnInit() {}
18void Controller_Gesture::OnRelease() {} 18void Controller_Gesture::OnRelease() {}
19 19
20void Controller_Gesture::OnUpdate(u8* data, std::size_t size) { 20void Controller_Gesture::OnUpdate(u8* data, std::size_t size) {
21 shared_memory.header.timestamp = CoreTiming::GetTicks(); 21 shared_memory.header.timestamp = Core::Timing::GetTicks();
22 shared_memory.header.total_entry_count = 17; 22 shared_memory.header.total_entry_count = 17;
23 23
24 if (!IsControllerActivated()) { 24 if (!IsControllerActivated()) {
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index ca75adc2b..798f30436 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -20,7 +20,7 @@ void Controller_Keyboard::OnInit() {}
20void Controller_Keyboard::OnRelease() {} 20void Controller_Keyboard::OnRelease() {}
21 21
22void Controller_Keyboard::OnUpdate(u8* data, std::size_t size) { 22void Controller_Keyboard::OnUpdate(u8* data, std::size_t size) {
23 shared_memory.header.timestamp = CoreTiming::GetTicks(); 23 shared_memory.header.timestamp = Core::Timing::GetTicks();
24 shared_memory.header.total_entry_count = 17; 24 shared_memory.header.total_entry_count = 17;
25 25
26 if (!IsControllerActivated()) { 26 if (!IsControllerActivated()) {
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp
index 63391dbe9..4985037be 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/core/hle/service/hid/controllers/mouse.cpp
@@ -18,7 +18,7 @@ void Controller_Mouse::OnInit() {}
18void Controller_Mouse::OnRelease() {} 18void Controller_Mouse::OnRelease() {}
19 19
20void Controller_Mouse::OnUpdate(u8* data, std::size_t size) { 20void Controller_Mouse::OnUpdate(u8* data, std::size_t size) {
21 shared_memory.header.timestamp = CoreTiming::GetTicks(); 21 shared_memory.header.timestamp = Core::Timing::GetTicks();
22 shared_memory.header.total_entry_count = 17; 22 shared_memory.header.total_entry_count = 17;
23 23
24 if (!IsControllerActivated()) { 24 if (!IsControllerActivated()) {
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 04c8c35a8..ffdd1c593 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -308,7 +308,7 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
308 const auto& last_entry = 308 const auto& last_entry =
309 main_controller->npad[main_controller->common.last_entry_index]; 309 main_controller->npad[main_controller->common.last_entry_index];
310 310
311 main_controller->common.timestamp = CoreTiming::GetTicks(); 311 main_controller->common.timestamp = Core::Timing::GetTicks();
312 main_controller->common.last_entry_index = 312 main_controller->common.last_entry_index =
313 (main_controller->common.last_entry_index + 1) % 17; 313 (main_controller->common.last_entry_index + 1) % 17;
314 314
diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp
index 02fcfadd9..cca4dca1d 100644
--- a/src/core/hle/service/hid/controllers/stubbed.cpp
+++ b/src/core/hle/service/hid/controllers/stubbed.cpp
@@ -22,7 +22,7 @@ void Controller_Stubbed::OnUpdate(u8* data, std::size_t size) {
22 } 22 }
23 23
24 CommonHeader header{}; 24 CommonHeader header{};
25 header.timestamp = CoreTiming::GetTicks(); 25 header.timestamp = Core::Timing::GetTicks();
26 header.total_entry_count = 17; 26 header.total_entry_count = 17;
27 header.entry_count = 0; 27 header.entry_count = 0;
28 header.last_entry_index = 0; 28 header.last_entry_index = 0;
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index f666b1bd8..a7c8acc72 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -21,7 +21,7 @@ void Controller_Touchscreen::OnInit() {}
21void Controller_Touchscreen::OnRelease() {} 21void Controller_Touchscreen::OnRelease() {}
22 22
23void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) { 23void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) {
24 shared_memory.header.timestamp = CoreTiming::GetTicks(); 24 shared_memory.header.timestamp = Core::Timing::GetTicks();
25 shared_memory.header.total_entry_count = 17; 25 shared_memory.header.total_entry_count = 17;
26 26
27 if (!IsControllerActivated()) { 27 if (!IsControllerActivated()) {
@@ -48,7 +48,7 @@ void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) {
48 touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; 48 touch_entry.diameter_x = Settings::values.touchscreen.diameter_x;
49 touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; 49 touch_entry.diameter_y = Settings::values.touchscreen.diameter_y;
50 touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; 50 touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle;
51 const u64 tick = CoreTiming::GetTicks(); 51 const u64 tick = Core::Timing::GetTicks();
52 touch_entry.delta_time = tick - last_touch; 52 touch_entry.delta_time = tick - last_touch;
53 last_touch = tick; 53 last_touch = tick;
54 touch_entry.finger = Settings::values.touchscreen.finger; 54 touch_entry.finger = Settings::values.touchscreen.finger;
diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp
index cd397c70b..eff03d14e 100644
--- a/src/core/hle/service/hid/controllers/xpad.cpp
+++ b/src/core/hle/service/hid/controllers/xpad.cpp
@@ -19,7 +19,7 @@ void Controller_XPad::OnRelease() {}
19 19
20void Controller_XPad::OnUpdate(u8* data, std::size_t size) { 20void Controller_XPad::OnUpdate(u8* data, std::size_t size) {
21 for (auto& xpad_entry : shared_memory.shared_memory_entries) { 21 for (auto& xpad_entry : shared_memory.shared_memory_entries) {
22 xpad_entry.header.timestamp = CoreTiming::GetTicks(); 22 xpad_entry.header.timestamp = Core::Timing::GetTicks();
23 xpad_entry.header.total_entry_count = 17; 23 xpad_entry.header.total_entry_count = 17;
24 24
25 if (!IsControllerActivated()) { 25 if (!IsControllerActivated()) {
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 008bf3f02..79c320d04 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -36,9 +36,9 @@ namespace Service::HID {
36 36
37// Updating period for each HID device. 37// Updating period for each HID device.
38// TODO(ogniK): Find actual polling rate of hid 38// TODO(ogniK): Find actual polling rate of hid
39constexpr u64 pad_update_ticks = CoreTiming::BASE_CLOCK_RATE / 66; 39constexpr u64 pad_update_ticks = Core::Timing::BASE_CLOCK_RATE / 66;
40constexpr u64 accelerometer_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; 40constexpr u64 accelerometer_update_ticks = Core::Timing::BASE_CLOCK_RATE / 100;
41constexpr u64 gyroscope_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; 41constexpr u64 gyroscope_update_ticks = Core::Timing::BASE_CLOCK_RATE / 100;
42constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; 42constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
43 43
44IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") { 44IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") {
@@ -73,14 +73,13 @@ IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") {
73 GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000); 73 GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000);
74 74
75 // Register update callbacks 75 // Register update callbacks
76 pad_update_event = 76 pad_update_event = Core::Timing::RegisterEvent(
77 CoreTiming::RegisterEvent("HID::UpdatePadCallback", [this](u64 userdata, int cycles_late) { 77 "HID::UpdatePadCallback",
78 UpdateControllers(userdata, cycles_late); 78 [this](u64 userdata, int cycles_late) { UpdateControllers(userdata, cycles_late); });
79 });
80 79
81 // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) 80 // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
82 81
83 CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event); 82 Core::Timing::ScheduleEvent(pad_update_ticks, pad_update_event);
84 83
85 ReloadInputDevices(); 84 ReloadInputDevices();
86} 85}
@@ -94,7 +93,7 @@ void IAppletResource::DeactivateController(HidController controller) {
94} 93}
95 94
96IAppletResource ::~IAppletResource() { 95IAppletResource ::~IAppletResource() {
97 CoreTiming::UnscheduleEvent(pad_update_event, 0); 96 Core::Timing::UnscheduleEvent(pad_update_event, 0);
98} 97}
99 98
100void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { 99void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
@@ -114,7 +113,7 @@ void IAppletResource::UpdateControllers(u64 userdata, int cycles_late) {
114 controller->OnUpdate(shared_mem->GetPointer(), SHARED_MEMORY_SIZE); 113 controller->OnUpdate(shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
115 } 114 }
116 115
117 CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event); 116 Core::Timing::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
118} 117}
119 118
120class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { 119class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index eca27c056..6d897c842 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -7,7 +7,7 @@
7#include "controllers/controller_base.h" 7#include "controllers/controller_base.h"
8#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
9 9
10namespace CoreTiming { 10namespace Core::Timing {
11struct EventType; 11struct EventType;
12} 12}
13 13
@@ -66,7 +66,7 @@ private:
66 66
67 Kernel::SharedPtr<Kernel::SharedMemory> shared_mem; 67 Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
68 68
69 CoreTiming::EventType* pad_update_event; 69 Core::Timing::EventType* pad_update_event;
70 70
71 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)> 71 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
72 controllers{}; 72 controllers{};
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 3c7f8b1ee..b427d4068 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -98,7 +98,7 @@ void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) {
98 98
99 IPC::ResponseBuilder rb{ctx, 5}; 99 IPC::ResponseBuilder rb{ctx, 5};
100 rb.Push(RESULT_SUCCESS); 100 rb.Push(RESULT_SUCCESS);
101 rb.PushRaw<u64>(CoreTiming::GetTicks()); 101 rb.PushRaw<u64>(Core::Timing::GetTicks());
102 rb.PushRaw<u32>(0); 102 rb.PushRaw<u32>(0);
103} 103}
104 104
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index d57a54ee8..88d80ba06 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -184,7 +184,7 @@ u32 nvhost_ctrl_gpu::GetGpuTime(const std::vector<u8>& input, std::vector<u8>& o
184 184
185 IoctlGetGpuTime params{}; 185 IoctlGetGpuTime params{};
186 std::memcpy(&params, input.data(), input.size()); 186 std::memcpy(&params, input.data(), input.size());
187 params.gpu_time = CoreTiming::cyclesToNs(CoreTiming::GetTicks()); 187 params.gpu_time = Core::Timing::cyclesToNs(Core::Timing::GetTicks());
188 std::memcpy(output.data(), &params, output.size()); 188 std::memcpy(output.data(), &params, output.size());
189 return 0; 189 return 0;
190} 190}
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index b171f256c..ab90d591e 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -13,10 +13,6 @@
13#include "core/hle/kernel/object.h" 13#include "core/hle/kernel/object.h"
14#include "core/hle/kernel/writable_event.h" 14#include "core/hle/kernel/writable_event.h"
15 15
16namespace CoreTiming {
17struct EventType;
18}
19
20namespace Service::NVFlinger { 16namespace Service::NVFlinger {
21 17
22struct IGBPBuffer { 18struct IGBPBuffer {
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index cde06916d..ce1b59860 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -25,21 +25,21 @@
25namespace Service::NVFlinger { 25namespace Service::NVFlinger {
26 26
27constexpr std::size_t SCREEN_REFRESH_RATE = 60; 27constexpr std::size_t SCREEN_REFRESH_RATE = 60;
28constexpr u64 frame_ticks = static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / SCREEN_REFRESH_RATE); 28constexpr u64 frame_ticks = static_cast<u64>(Core::Timing::BASE_CLOCK_RATE / SCREEN_REFRESH_RATE);
29 29
30NVFlinger::NVFlinger() { 30NVFlinger::NVFlinger() {
31 // Schedule the screen composition events 31 // Schedule the screen composition events
32 composition_event = 32 composition_event =
33 CoreTiming::RegisterEvent("ScreenComposition", [this](u64 userdata, int cycles_late) { 33 Core::Timing::RegisterEvent("ScreenComposition", [this](u64 userdata, int cycles_late) {
34 Compose(); 34 Compose();
35 CoreTiming::ScheduleEvent(frame_ticks - cycles_late, composition_event); 35 Core::Timing::ScheduleEvent(frame_ticks - cycles_late, composition_event);
36 }); 36 });
37 37
38 CoreTiming::ScheduleEvent(frame_ticks, composition_event); 38 Core::Timing::ScheduleEvent(frame_ticks, composition_event);
39} 39}
40 40
41NVFlinger::~NVFlinger() { 41NVFlinger::~NVFlinger() {
42 CoreTiming::UnscheduleEvent(composition_event, 0); 42 Core::Timing::UnscheduleEvent(composition_event, 0);
43} 43}
44 44
45void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { 45void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 4c55e99f4..6d8bcbd30 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -14,7 +14,7 @@
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "core/hle/kernel/object.h" 15#include "core/hle/kernel/object.h"
16 16
17namespace CoreTiming { 17namespace Core::Timing {
18struct EventType; 18struct EventType;
19} 19}
20 20
@@ -115,8 +115,8 @@ private:
115 /// layers. 115 /// layers.
116 u32 next_buffer_queue_id = 1; 116 u32 next_buffer_queue_id = 1;
117 117
118 /// CoreTiming event that handles screen composition. 118 /// Event that handles screen composition.
119 CoreTiming::EventType* composition_event; 119 Core::Timing::EventType* composition_event;
120}; 120};
121 121
122} // namespace Service::NVFlinger 122} // namespace Service::NVFlinger
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index c13640ad8..efebd1b24 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -106,8 +106,8 @@ private:
106 void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) { 106 void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) {
107 LOG_DEBUG(Service_Time, "called"); 107 LOG_DEBUG(Service_Time, "called");
108 108
109 SteadyClockTimePoint steady_clock_time_point{ 109 const SteadyClockTimePoint steady_clock_time_point{
110 CoreTiming::cyclesToMs(CoreTiming::GetTicks()) / 1000}; 110 Core::Timing::cyclesToMs(Core::Timing::GetTicks()) / 1000};
111 IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2}; 111 IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2};
112 rb.Push(RESULT_SUCCESS); 112 rb.Push(RESULT_SUCCESS);
113 rb.PushRaw(steady_clock_time_point); 113 rb.PushRaw(steady_clock_time_point);
@@ -282,7 +282,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
282 } 282 }
283 283
284 const SteadyClockTimePoint steady_clock_time_point{ 284 const SteadyClockTimePoint steady_clock_time_point{
285 CoreTiming::cyclesToMs(CoreTiming::GetTicks()) / 1000, {}}; 285 Core::Timing::cyclesToMs(Core::Timing::GetTicks()) / 1000, {}};
286 286
287 CalendarTime calendar_time{}; 287 CalendarTime calendar_time{};
288 calendar_time.year = tm->tm_year + 1900; 288 calendar_time.year = tm->tm_year + 1900;
diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp
index 2242c14cf..77607a755 100644
--- a/src/tests/core/core_timing.cpp
+++ b/src/tests/core/core_timing.cpp
@@ -31,10 +31,10 @@ void CallbackTemplate(u64 userdata, s64 cycles_late) {
31class ScopeInit final { 31class ScopeInit final {
32public: 32public:
33 ScopeInit() { 33 ScopeInit() {
34 CoreTiming::Init(); 34 Core::Timing::Init();
35 } 35 }
36 ~ScopeInit() { 36 ~ScopeInit() {
37 CoreTiming::Shutdown(); 37 Core::Timing::Shutdown();
38 } 38 }
39}; 39};
40 40
@@ -44,37 +44,37 @@ static void AdvanceAndCheck(u32 idx, int downcount, int expected_lateness = 0,
44 expected_callback = CB_IDS[idx]; 44 expected_callback = CB_IDS[idx];
45 lateness = expected_lateness; 45 lateness = expected_lateness;
46 46
47 CoreTiming::AddTicks(CoreTiming::GetDowncount() - 47 // Pretend we executed X cycles of instructions.
48 cpu_downcount); // Pretend we executed X cycles of instructions. 48 Core::Timing::AddTicks(Core::Timing::GetDowncount() - cpu_downcount);
49 CoreTiming::Advance(); 49 Core::Timing::Advance();
50 50
51 REQUIRE(decltype(callbacks_ran_flags)().set(idx) == callbacks_ran_flags); 51 REQUIRE(decltype(callbacks_ran_flags)().set(idx) == callbacks_ran_flags);
52 REQUIRE(downcount == CoreTiming::GetDowncount()); 52 REQUIRE(downcount == Core::Timing::GetDowncount());
53} 53}
54 54
55TEST_CASE("CoreTiming[BasicOrder]", "[core]") { 55TEST_CASE("CoreTiming[BasicOrder]", "[core]") {
56 ScopeInit guard; 56 ScopeInit guard;
57 57
58 CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>); 58 Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>);
59 CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>); 59 Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>);
60 CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", CallbackTemplate<2>); 60 Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", CallbackTemplate<2>);
61 CoreTiming::EventType* cb_d = CoreTiming::RegisterEvent("callbackD", CallbackTemplate<3>); 61 Core::Timing::EventType* cb_d = Core::Timing::RegisterEvent("callbackD", CallbackTemplate<3>);
62 CoreTiming::EventType* cb_e = CoreTiming::RegisterEvent("callbackE", CallbackTemplate<4>); 62 Core::Timing::EventType* cb_e = Core::Timing::RegisterEvent("callbackE", CallbackTemplate<4>);
63 63
64 // Enter slice 0 64 // Enter slice 0
65 CoreTiming::Advance(); 65 Core::Timing::Advance();
66 66
67 // D -> B -> C -> A -> E 67 // D -> B -> C -> A -> E
68 CoreTiming::ScheduleEvent(1000, cb_a, CB_IDS[0]); 68 Core::Timing::ScheduleEvent(1000, cb_a, CB_IDS[0]);
69 REQUIRE(1000 == CoreTiming::GetDowncount()); 69 REQUIRE(1000 == Core::Timing::GetDowncount());
70 CoreTiming::ScheduleEvent(500, cb_b, CB_IDS[1]); 70 Core::Timing::ScheduleEvent(500, cb_b, CB_IDS[1]);
71 REQUIRE(500 == CoreTiming::GetDowncount()); 71 REQUIRE(500 == Core::Timing::GetDowncount());
72 CoreTiming::ScheduleEvent(800, cb_c, CB_IDS[2]); 72 Core::Timing::ScheduleEvent(800, cb_c, CB_IDS[2]);
73 REQUIRE(500 == CoreTiming::GetDowncount()); 73 REQUIRE(500 == Core::Timing::GetDowncount());
74 CoreTiming::ScheduleEvent(100, cb_d, CB_IDS[3]); 74 Core::Timing::ScheduleEvent(100, cb_d, CB_IDS[3]);
75 REQUIRE(100 == CoreTiming::GetDowncount()); 75 REQUIRE(100 == Core::Timing::GetDowncount());
76 CoreTiming::ScheduleEvent(1200, cb_e, CB_IDS[4]); 76 Core::Timing::ScheduleEvent(1200, cb_e, CB_IDS[4]);
77 REQUIRE(100 == CoreTiming::GetDowncount()); 77 REQUIRE(100 == Core::Timing::GetDowncount());
78 78
79 AdvanceAndCheck(3, 400); 79 AdvanceAndCheck(3, 400);
80 AdvanceAndCheck(1, 300); 80 AdvanceAndCheck(1, 300);
@@ -86,36 +86,36 @@ TEST_CASE("CoreTiming[BasicOrder]", "[core]") {
86TEST_CASE("CoreTiming[Threadsave]", "[core]") { 86TEST_CASE("CoreTiming[Threadsave]", "[core]") {
87 ScopeInit guard; 87 ScopeInit guard;
88 88
89 CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>); 89 Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>);
90 CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>); 90 Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>);
91 CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", CallbackTemplate<2>); 91 Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", CallbackTemplate<2>);
92 CoreTiming::EventType* cb_d = CoreTiming::RegisterEvent("callbackD", CallbackTemplate<3>); 92 Core::Timing::EventType* cb_d = Core::Timing::RegisterEvent("callbackD", CallbackTemplate<3>);
93 CoreTiming::EventType* cb_e = CoreTiming::RegisterEvent("callbackE", CallbackTemplate<4>); 93 Core::Timing::EventType* cb_e = Core::Timing::RegisterEvent("callbackE", CallbackTemplate<4>);
94 94
95 // Enter slice 0 95 // Enter slice 0
96 CoreTiming::Advance(); 96 Core::Timing::Advance();
97 97
98 // D -> B -> C -> A -> E 98 // D -> B -> C -> A -> E
99 CoreTiming::ScheduleEventThreadsafe(1000, cb_a, CB_IDS[0]); 99 Core::Timing::ScheduleEventThreadsafe(1000, cb_a, CB_IDS[0]);
100 // Manually force since ScheduleEventThreadsafe doesn't call it 100 // Manually force since ScheduleEventThreadsafe doesn't call it
101 CoreTiming::ForceExceptionCheck(1000); 101 Core::Timing::ForceExceptionCheck(1000);
102 REQUIRE(1000 == CoreTiming::GetDowncount()); 102 REQUIRE(1000 == Core::Timing::GetDowncount());
103 CoreTiming::ScheduleEventThreadsafe(500, cb_b, CB_IDS[1]); 103 Core::Timing::ScheduleEventThreadsafe(500, cb_b, CB_IDS[1]);
104 // Manually force since ScheduleEventThreadsafe doesn't call it 104 // Manually force since ScheduleEventThreadsafe doesn't call it
105 CoreTiming::ForceExceptionCheck(500); 105 Core::Timing::ForceExceptionCheck(500);
106 REQUIRE(500 == CoreTiming::GetDowncount()); 106 REQUIRE(500 == Core::Timing::GetDowncount());
107 CoreTiming::ScheduleEventThreadsafe(800, cb_c, CB_IDS[2]); 107 Core::Timing::ScheduleEventThreadsafe(800, cb_c, CB_IDS[2]);
108 // Manually force since ScheduleEventThreadsafe doesn't call it 108 // Manually force since ScheduleEventThreadsafe doesn't call it
109 CoreTiming::ForceExceptionCheck(800); 109 Core::Timing::ForceExceptionCheck(800);
110 REQUIRE(500 == CoreTiming::GetDowncount()); 110 REQUIRE(500 == Core::Timing::GetDowncount());
111 CoreTiming::ScheduleEventThreadsafe(100, cb_d, CB_IDS[3]); 111 Core::Timing::ScheduleEventThreadsafe(100, cb_d, CB_IDS[3]);
112 // Manually force since ScheduleEventThreadsafe doesn't call it 112 // Manually force since ScheduleEventThreadsafe doesn't call it
113 CoreTiming::ForceExceptionCheck(100); 113 Core::Timing::ForceExceptionCheck(100);
114 REQUIRE(100 == CoreTiming::GetDowncount()); 114 REQUIRE(100 == Core::Timing::GetDowncount());
115 CoreTiming::ScheduleEventThreadsafe(1200, cb_e, CB_IDS[4]); 115 Core::Timing::ScheduleEventThreadsafe(1200, cb_e, CB_IDS[4]);
116 // Manually force since ScheduleEventThreadsafe doesn't call it 116 // Manually force since ScheduleEventThreadsafe doesn't call it
117 CoreTiming::ForceExceptionCheck(1200); 117 Core::Timing::ForceExceptionCheck(1200);
118 REQUIRE(100 == CoreTiming::GetDowncount()); 118 REQUIRE(100 == Core::Timing::GetDowncount());
119 119
120 AdvanceAndCheck(3, 400); 120 AdvanceAndCheck(3, 400);
121 AdvanceAndCheck(1, 300); 121 AdvanceAndCheck(1, 300);
@@ -143,42 +143,42 @@ TEST_CASE("CoreTiming[SharedSlot]", "[core]") {
143 143
144 ScopeInit guard; 144 ScopeInit guard;
145 145
146 CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", FifoCallback<0>); 146 Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", FifoCallback<0>);
147 CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", FifoCallback<1>); 147 Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", FifoCallback<1>);
148 CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", FifoCallback<2>); 148 Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", FifoCallback<2>);
149 CoreTiming::EventType* cb_d = CoreTiming::RegisterEvent("callbackD", FifoCallback<3>); 149 Core::Timing::EventType* cb_d = Core::Timing::RegisterEvent("callbackD", FifoCallback<3>);
150 CoreTiming::EventType* cb_e = CoreTiming::RegisterEvent("callbackE", FifoCallback<4>); 150 Core::Timing::EventType* cb_e = Core::Timing::RegisterEvent("callbackE", FifoCallback<4>);
151 151
152 CoreTiming::ScheduleEvent(1000, cb_a, CB_IDS[0]); 152 Core::Timing::ScheduleEvent(1000, cb_a, CB_IDS[0]);
153 CoreTiming::ScheduleEvent(1000, cb_b, CB_IDS[1]); 153 Core::Timing::ScheduleEvent(1000, cb_b, CB_IDS[1]);
154 CoreTiming::ScheduleEvent(1000, cb_c, CB_IDS[2]); 154 Core::Timing::ScheduleEvent(1000, cb_c, CB_IDS[2]);
155 CoreTiming::ScheduleEvent(1000, cb_d, CB_IDS[3]); 155 Core::Timing::ScheduleEvent(1000, cb_d, CB_IDS[3]);
156 CoreTiming::ScheduleEvent(1000, cb_e, CB_IDS[4]); 156 Core::Timing::ScheduleEvent(1000, cb_e, CB_IDS[4]);
157 157
158 // Enter slice 0 158 // Enter slice 0
159 CoreTiming::Advance(); 159 Core::Timing::Advance();
160 REQUIRE(1000 == CoreTiming::GetDowncount()); 160 REQUIRE(1000 == Core::Timing::GetDowncount());
161 161
162 callbacks_ran_flags = 0; 162 callbacks_ran_flags = 0;
163 counter = 0; 163 counter = 0;
164 lateness = 0; 164 lateness = 0;
165 CoreTiming::AddTicks(CoreTiming::GetDowncount()); 165 Core::Timing::AddTicks(Core::Timing::GetDowncount());
166 CoreTiming::Advance(); 166 Core::Timing::Advance();
167 REQUIRE(MAX_SLICE_LENGTH == CoreTiming::GetDowncount()); 167 REQUIRE(MAX_SLICE_LENGTH == Core::Timing::GetDowncount());
168 REQUIRE(0x1FULL == callbacks_ran_flags.to_ullong()); 168 REQUIRE(0x1FULL == callbacks_ran_flags.to_ullong());
169} 169}
170 170
171TEST_CASE("CoreTiming[PredictableLateness]", "[core]") { 171TEST_CASE("Core::Timing[PredictableLateness]", "[core]") {
172 ScopeInit guard; 172 ScopeInit guard;
173 173
174 CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>); 174 Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>);
175 CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>); 175 Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>);
176 176
177 // Enter slice 0 177 // Enter slice 0
178 CoreTiming::Advance(); 178 Core::Timing::Advance();
179 179
180 CoreTiming::ScheduleEvent(100, cb_a, CB_IDS[0]); 180 Core::Timing::ScheduleEvent(100, cb_a, CB_IDS[0]);
181 CoreTiming::ScheduleEvent(200, cb_b, CB_IDS[1]); 181 Core::Timing::ScheduleEvent(200, cb_b, CB_IDS[1]);
182 182
183 AdvanceAndCheck(0, 90, 10, -10); // (100 - 10) 183 AdvanceAndCheck(0, 90, 10, -10); // (100 - 10)
184 AdvanceAndCheck(1, MAX_SLICE_LENGTH, 50, -50); 184 AdvanceAndCheck(1, MAX_SLICE_LENGTH, 50, -50);
@@ -192,9 +192,10 @@ static void RescheduleCallback(u64 userdata, s64 cycles_late) {
192 REQUIRE(reschedules >= 0); 192 REQUIRE(reschedules >= 0);
193 REQUIRE(lateness == cycles_late); 193 REQUIRE(lateness == cycles_late);
194 194
195 if (reschedules > 0) 195 if (reschedules > 0) {
196 CoreTiming::ScheduleEvent(1000, reinterpret_cast<CoreTiming::EventType*>(userdata), 196 Core::Timing::ScheduleEvent(1000, reinterpret_cast<Core::Timing::EventType*>(userdata),
197 userdata); 197 userdata);
198 }
198} 199}
199} // namespace ChainSchedulingTest 200} // namespace ChainSchedulingTest
200 201
@@ -203,35 +204,35 @@ TEST_CASE("CoreTiming[ChainScheduling]", "[core]") {
203 204
204 ScopeInit guard; 205 ScopeInit guard;
205 206
206 CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>); 207 Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>);
207 CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>); 208 Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>);
208 CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", CallbackTemplate<2>); 209 Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", CallbackTemplate<2>);
209 CoreTiming::EventType* cb_rs = 210 Core::Timing::EventType* cb_rs =
210 CoreTiming::RegisterEvent("callbackReschedule", RescheduleCallback); 211 Core::Timing::RegisterEvent("callbackReschedule", RescheduleCallback);
211 212
212 // Enter slice 0 213 // Enter slice 0
213 CoreTiming::Advance(); 214 Core::Timing::Advance();
214 215
215 CoreTiming::ScheduleEvent(800, cb_a, CB_IDS[0]); 216 Core::Timing::ScheduleEvent(800, cb_a, CB_IDS[0]);
216 CoreTiming::ScheduleEvent(1000, cb_b, CB_IDS[1]); 217 Core::Timing::ScheduleEvent(1000, cb_b, CB_IDS[1]);
217 CoreTiming::ScheduleEvent(2200, cb_c, CB_IDS[2]); 218 Core::Timing::ScheduleEvent(2200, cb_c, CB_IDS[2]);
218 CoreTiming::ScheduleEvent(1000, cb_rs, reinterpret_cast<u64>(cb_rs)); 219 Core::Timing::ScheduleEvent(1000, cb_rs, reinterpret_cast<u64>(cb_rs));
219 REQUIRE(800 == CoreTiming::GetDowncount()); 220 REQUIRE(800 == Core::Timing::GetDowncount());
220 221
221 reschedules = 3; 222 reschedules = 3;
222 AdvanceAndCheck(0, 200); // cb_a 223 AdvanceAndCheck(0, 200); // cb_a
223 AdvanceAndCheck(1, 1000); // cb_b, cb_rs 224 AdvanceAndCheck(1, 1000); // cb_b, cb_rs
224 REQUIRE(2 == reschedules); 225 REQUIRE(2 == reschedules);
225 226
226 CoreTiming::AddTicks(CoreTiming::GetDowncount()); 227 Core::Timing::AddTicks(Core::Timing::GetDowncount());
227 CoreTiming::Advance(); // cb_rs 228 Core::Timing::Advance(); // cb_rs
228 REQUIRE(1 == reschedules); 229 REQUIRE(1 == reschedules);
229 REQUIRE(200 == CoreTiming::GetDowncount()); 230 REQUIRE(200 == Core::Timing::GetDowncount());
230 231
231 AdvanceAndCheck(2, 800); // cb_c 232 AdvanceAndCheck(2, 800); // cb_c
232 233
233 CoreTiming::AddTicks(CoreTiming::GetDowncount()); 234 Core::Timing::AddTicks(Core::Timing::GetDowncount());
234 CoreTiming::Advance(); // cb_rs 235 Core::Timing::Advance(); // cb_rs
235 REQUIRE(0 == reschedules); 236 REQUIRE(0 == reschedules);
236 REQUIRE(MAX_SLICE_LENGTH == CoreTiming::GetDowncount()); 237 REQUIRE(MAX_SLICE_LENGTH == Core::Timing::GetDowncount());
237} 238}
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 33e507e69..1db0d031d 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -5,12 +5,12 @@ add_library(video_core STATIC
5 debug_utils/debug_utils.h 5 debug_utils/debug_utils.h
6 engines/fermi_2d.cpp 6 engines/fermi_2d.cpp
7 engines/fermi_2d.h 7 engines/fermi_2d.h
8 engines/kepler_compute.cpp
9 engines/kepler_compute.h
8 engines/kepler_memory.cpp 10 engines/kepler_memory.cpp
9 engines/kepler_memory.h 11 engines/kepler_memory.h
10 engines/maxwell_3d.cpp 12 engines/maxwell_3d.cpp
11 engines/maxwell_3d.h 13 engines/maxwell_3d.h
12 engines/maxwell_compute.cpp
13 engines/maxwell_compute.h
14 engines/maxwell_dma.cpp 14 engines/maxwell_dma.cpp
15 engines/maxwell_dma.h 15 engines/maxwell_dma.h
16 engines/shader_bytecode.h 16 engines/shader_bytecode.h
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp
new file mode 100644
index 000000000..4ca856b6b
--- /dev/null
+++ b/src/video_core/engines/kepler_compute.cpp
@@ -0,0 +1,34 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6#include "core/core.h"
7#include "core/memory.h"
8#include "video_core/engines/kepler_compute.h"
9#include "video_core/memory_manager.h"
10
11namespace Tegra::Engines {
12
13KeplerCompute::KeplerCompute(MemoryManager& memory_manager) : memory_manager{memory_manager} {}
14
15KeplerCompute::~KeplerCompute() = default;
16
17void KeplerCompute::CallMethod(const GPU::MethodCall& method_call) {
18 ASSERT_MSG(method_call.method < Regs::NUM_REGS,
19 "Invalid KeplerCompute register, increase the size of the Regs structure");
20
21 regs.reg_array[method_call.method] = method_call.argument;
22
23 switch (method_call.method) {
24 case KEPLER_COMPUTE_REG_INDEX(launch):
25 // Abort execution since compute shaders can be used to alter game memory (e.g. CUDA
26 // kernels)
27 UNREACHABLE_MSG("Compute shaders are not implemented");
28 break;
29 default:
30 break;
31 }
32}
33
34} // namespace Tegra::Engines
diff --git a/src/video_core/engines/maxwell_compute.h b/src/video_core/engines/kepler_compute.h
index 1d71f11bd..df0a32e0f 100644
--- a/src/video_core/engines/maxwell_compute.h
+++ b/src/video_core/engines/kepler_compute.h
@@ -10,47 +10,48 @@
10#include "common/common_funcs.h" 10#include "common/common_funcs.h"
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "video_core/gpu.h" 12#include "video_core/gpu.h"
13#include "video_core/memory_manager.h"
13 14
14namespace Tegra::Engines { 15namespace Tegra::Engines {
15 16
16#define MAXWELL_COMPUTE_REG_INDEX(field_name) \ 17#define KEPLER_COMPUTE_REG_INDEX(field_name) \
17 (offsetof(Tegra::Engines::MaxwellCompute::Regs, field_name) / sizeof(u32)) 18 (offsetof(Tegra::Engines::KeplerCompute::Regs, field_name) / sizeof(u32))
18 19
19class MaxwellCompute final { 20class KeplerCompute final {
20public: 21public:
21 MaxwellCompute() = default; 22 explicit KeplerCompute(MemoryManager& memory_manager);
22 ~MaxwellCompute() = default; 23 ~KeplerCompute();
24
25 static constexpr std::size_t NumConstBuffers = 8;
23 26
24 struct Regs { 27 struct Regs {
25 static constexpr std::size_t NUM_REGS = 0xCF8; 28 static constexpr std::size_t NUM_REGS = 0xCF8;
26 29
27 union { 30 union {
28 struct { 31 struct {
29 INSERT_PADDING_WORDS(0x281); 32 INSERT_PADDING_WORDS(0xAF);
30 33
31 union { 34 u32 launch;
32 u32 compute_end;
33 BitField<0, 1, u32> unknown;
34 } compute;
35 35
36 INSERT_PADDING_WORDS(0xA76); 36 INSERT_PADDING_WORDS(0xC48);
37 }; 37 };
38 std::array<u32, NUM_REGS> reg_array; 38 std::array<u32, NUM_REGS> reg_array;
39 }; 39 };
40 } regs{}; 40 } regs{};
41
42 static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), 41 static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32),
43 "MaxwellCompute Regs has wrong size"); 42 "KeplerCompute Regs has wrong size");
43
44 MemoryManager& memory_manager;
44 45
45 /// Write the value to the register identified by method. 46 /// Write the value to the register identified by method.
46 void CallMethod(const GPU::MethodCall& method_call); 47 void CallMethod(const GPU::MethodCall& method_call);
47}; 48};
48 49
49#define ASSERT_REG_POSITION(field_name, position) \ 50#define ASSERT_REG_POSITION(field_name, position) \
50 static_assert(offsetof(MaxwellCompute::Regs, field_name) == position * 4, \ 51 static_assert(offsetof(KeplerCompute::Regs, field_name) == position * 4, \
51 "Field " #field_name " has invalid position") 52 "Field " #field_name " has invalid position")
52 53
53ASSERT_REG_POSITION(compute, 0x281); 54ASSERT_REG_POSITION(launch, 0xAF);
54 55
55#undef ASSERT_REG_POSITION 56#undef ASSERT_REG_POSITION
56 57
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 10eae6a65..19b6b14b2 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -317,7 +317,7 @@ void Maxwell3D::ProcessQueryGet() {
317 LongQueryResult query_result{}; 317 LongQueryResult query_result{};
318 query_result.value = result; 318 query_result.value = result;
319 // TODO(Subv): Generate a real GPU timestamp and write it here instead of CoreTiming 319 // TODO(Subv): Generate a real GPU timestamp and write it here instead of CoreTiming
320 query_result.timestamp = CoreTiming::GetTicks(); 320 query_result.timestamp = Core::Timing::GetTicks();
321 Memory::WriteBlock(*address, &query_result, sizeof(query_result)); 321 Memory::WriteBlock(*address, &query_result, sizeof(query_result));
322 } 322 }
323 dirty_flags.OnMemoryWrite(); 323 dirty_flags.OnMemoryWrite();
diff --git a/src/video_core/engines/maxwell_compute.cpp b/src/video_core/engines/maxwell_compute.cpp
deleted file mode 100644
index 656db6a61..000000000
--- a/src/video_core/engines/maxwell_compute.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6#include "core/core.h"
7#include "video_core/engines/maxwell_compute.h"
8
9namespace Tegra::Engines {
10
11void MaxwellCompute::CallMethod(const GPU::MethodCall& method_call) {
12 ASSERT_MSG(method_call.method < Regs::NUM_REGS,
13 "Invalid MaxwellCompute register, increase the size of the Regs structure");
14
15 regs.reg_array[method_call.method] = method_call.argument;
16
17 switch (method_call.method) {
18 case MAXWELL_COMPUTE_REG_INDEX(compute): {
19 LOG_CRITICAL(HW_GPU, "Compute shaders are not implemented");
20 UNREACHABLE();
21 break;
22 }
23 default:
24 break;
25 }
26}
27
28} // namespace Tegra::Engines
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 269df9437..1f425f90b 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -186,7 +186,7 @@ enum class SubOp : u64 {
186}; 186};
187 187
188enum class F2iRoundingOp : u64 { 188enum class F2iRoundingOp : u64 {
189 None = 0, 189 RoundEven = 0,
190 Floor = 1, 190 Floor = 1,
191 Ceil = 2, 191 Ceil = 2,
192 Trunc = 3, 192 Trunc = 3,
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 07d4ad9f7..3d00c308b 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -6,9 +6,9 @@
6#include "core/core_timing.h" 6#include "core/core_timing.h"
7#include "core/memory.h" 7#include "core/memory.h"
8#include "video_core/engines/fermi_2d.h" 8#include "video_core/engines/fermi_2d.h"
9#include "video_core/engines/kepler_compute.h"
9#include "video_core/engines/kepler_memory.h" 10#include "video_core/engines/kepler_memory.h"
10#include "video_core/engines/maxwell_3d.h" 11#include "video_core/engines/maxwell_3d.h"
11#include "video_core/engines/maxwell_compute.h"
12#include "video_core/engines/maxwell_dma.h" 12#include "video_core/engines/maxwell_dma.h"
13#include "video_core/gpu.h" 13#include "video_core/gpu.h"
14#include "video_core/rasterizer_interface.h" 14#include "video_core/rasterizer_interface.h"
@@ -32,7 +32,7 @@ GPU::GPU(VideoCore::RasterizerInterface& rasterizer) {
32 dma_pusher = std::make_unique<Tegra::DmaPusher>(*this); 32 dma_pusher = std::make_unique<Tegra::DmaPusher>(*this);
33 maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager); 33 maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager);
34 fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer, *memory_manager); 34 fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer, *memory_manager);
35 maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); 35 kepler_compute = std::make_unique<Engines::KeplerCompute>(*memory_manager);
36 maxwell_dma = std::make_unique<Engines::MaxwellDMA>(rasterizer, *memory_manager); 36 maxwell_dma = std::make_unique<Engines::MaxwellDMA>(rasterizer, *memory_manager);
37 kepler_memory = std::make_unique<Engines::KeplerMemory>(rasterizer, *memory_manager); 37 kepler_memory = std::make_unique<Engines::KeplerMemory>(rasterizer, *memory_manager);
38} 38}
@@ -246,8 +246,8 @@ void GPU::CallEngineMethod(const MethodCall& method_call) {
246 case EngineID::MAXWELL_B: 246 case EngineID::MAXWELL_B:
247 maxwell_3d->CallMethod(method_call); 247 maxwell_3d->CallMethod(method_call);
248 break; 248 break;
249 case EngineID::MAXWELL_COMPUTE_B: 249 case EngineID::KEPLER_COMPUTE_B:
250 maxwell_compute->CallMethod(method_call); 250 kepler_compute->CallMethod(method_call);
251 break; 251 break;
252 case EngineID::MAXWELL_DMA_COPY_A: 252 case EngineID::MAXWELL_DMA_COPY_A:
253 maxwell_dma->CallMethod(method_call); 253 maxwell_dma->CallMethod(method_call);
@@ -283,7 +283,7 @@ void GPU::ProcessSemaphoreTriggerMethod() {
283 block.sequence = regs.semaphore_sequence; 283 block.sequence = regs.semaphore_sequence;
284 // TODO(Kmather73): Generate a real GPU timestamp and write it here instead of 284 // TODO(Kmather73): Generate a real GPU timestamp and write it here instead of
285 // CoreTiming 285 // CoreTiming
286 block.timestamp = CoreTiming::GetTicks(); 286 block.timestamp = Core::Timing::GetTicks();
287 Memory::WriteBlock(*address, &block, sizeof(block)); 287 Memory::WriteBlock(*address, &block, sizeof(block));
288 } else { 288 } else {
289 const auto address = 289 const auto address =
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 19b62dc7e..a482196ea 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -103,15 +103,15 @@ struct FramebufferConfig {
103namespace Engines { 103namespace Engines {
104class Fermi2D; 104class Fermi2D;
105class Maxwell3D; 105class Maxwell3D;
106class MaxwellCompute;
107class MaxwellDMA; 106class MaxwellDMA;
107class KeplerCompute;
108class KeplerMemory; 108class KeplerMemory;
109} // namespace Engines 109} // namespace Engines
110 110
111enum class EngineID { 111enum class EngineID {
112 FERMI_TWOD_A = 0x902D, // 2D Engine 112 FERMI_TWOD_A = 0x902D, // 2D Engine
113 MAXWELL_B = 0xB197, // 3D Engine 113 MAXWELL_B = 0xB197, // 3D Engine
114 MAXWELL_COMPUTE_B = 0xB1C0, 114 KEPLER_COMPUTE_B = 0xB1C0,
115 KEPLER_INLINE_TO_MEMORY_B = 0xA140, 115 KEPLER_INLINE_TO_MEMORY_B = 0xA140,
116 MAXWELL_DMA_COPY_A = 0xB0B5, 116 MAXWELL_DMA_COPY_A = 0xB0B5,
117}; 117};
@@ -209,7 +209,7 @@ private:
209 /// 2D engine 209 /// 2D engine
210 std::unique_ptr<Engines::Fermi2D> fermi_2d; 210 std::unique_ptr<Engines::Fermi2D> fermi_2d;
211 /// Compute engine 211 /// Compute engine
212 std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; 212 std::unique_ptr<Engines::KeplerCompute> kepler_compute;
213 /// DMA engine 213 /// DMA engine
214 std::unique_ptr<Engines::MaxwellDMA> maxwell_dma; 214 std::unique_ptr<Engines::MaxwellDMA> maxwell_dma;
215 /// Inline memory engine 215 /// Inline memory engine
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 70e124dc4..b39bb4843 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -719,45 +719,51 @@ private:
719 constexpr std::array<const char*, 4> coord_constructors = {"float", "vec2", "vec3", "vec4"}; 719 constexpr std::array<const char*, 4> coord_constructors = {"float", "vec2", "vec3", "vec4"};
720 720
721 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); 721 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
722 const auto count = static_cast<u32>(operation.GetOperandsCount());
723 ASSERT(meta); 722 ASSERT(meta);
724 723
724 const auto count = static_cast<u32>(operation.GetOperandsCount());
725 const bool has_array = meta->sampler.IsArray();
726 const bool has_shadow = meta->sampler.IsShadow();
727
725 std::string expr = func; 728 std::string expr = func;
726 expr += '('; 729 expr += '(';
727 expr += GetSampler(meta->sampler); 730 expr += GetSampler(meta->sampler);
728 expr += ", "; 731 expr += ", ";
729 732
730 expr += coord_constructors[meta->coords_count - 1]; 733 expr += coord_constructors.at(count + (has_array ? 1 : 0) + (has_shadow ? 1 : 0) - 1);
731 expr += '('; 734 expr += '(';
732 for (u32 i = 0; i < count; ++i) { 735 for (u32 i = 0; i < count; ++i) {
733 const bool is_extra = i >= meta->coords_count; 736 expr += Visit(operation[i]);
734 const bool is_array = i == meta->array_index;
735
736 std::string operand = [&]() {
737 if (is_extra && is_extra_int) {
738 if (const auto immediate = std::get_if<ImmediateNode>(operation[i])) {
739 return std::to_string(static_cast<s32>(immediate->GetValue()));
740 } else {
741 return "ftoi(" + Visit(operation[i]) + ')';
742 }
743 } else {
744 return Visit(operation[i]);
745 }
746 }();
747 if (is_array) {
748 ASSERT(!is_extra);
749 operand = "float(ftoi(" + operand + "))";
750 }
751
752 expr += operand;
753 737
754 if (i + 1 == meta->coords_count) { 738 const u32 next = i + 1;
755 expr += ')'; 739 if (next < count || has_array || has_shadow)
756 } 740 expr += ", ";
757 if (i + 1 < count) { 741 }
742 if (has_array) {
743 expr += "float(ftoi(" + Visit(meta->array) + "))";
744 }
745 if (has_shadow) {
746 if (has_array)
758 expr += ", "; 747 expr += ", ";
748 expr += Visit(meta->depth_compare);
749 }
750 expr += ')';
751
752 for (const Node extra : meta->extras) {
753 expr += ", ";
754 if (is_extra_int) {
755 if (const auto immediate = std::get_if<ImmediateNode>(extra)) {
756 // Inline the string as an immediate integer in GLSL (some extra arguments are
757 // required to be constant)
758 expr += std::to_string(static_cast<s32>(immediate->GetValue()));
759 } else {
760 expr += "ftoi(" + Visit(extra) + ')';
761 }
762 } else {
763 expr += Visit(extra);
759 } 764 }
760 } 765 }
766
761 expr += ')'; 767 expr += ')';
762 return expr; 768 return expr;
763 } 769 }
@@ -1134,7 +1140,7 @@ private:
1134 Type::HalfFloat); 1140 Type::HalfFloat);
1135 } 1141 }
1136 1142
1137 std::string F4Texture(Operation operation) { 1143 std::string Texture(Operation operation) {
1138 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); 1144 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
1139 ASSERT(meta); 1145 ASSERT(meta);
1140 1146
@@ -1145,7 +1151,7 @@ private:
1145 return expr + GetSwizzle(meta->element); 1151 return expr + GetSwizzle(meta->element);
1146 } 1152 }
1147 1153
1148 std::string F4TextureLod(Operation operation) { 1154 std::string TextureLod(Operation operation) {
1149 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); 1155 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
1150 ASSERT(meta); 1156 ASSERT(meta);
1151 1157
@@ -1156,7 +1162,7 @@ private:
1156 return expr + GetSwizzle(meta->element); 1162 return expr + GetSwizzle(meta->element);
1157 } 1163 }
1158 1164
1159 std::string F4TextureGather(Operation operation) { 1165 std::string TextureGather(Operation operation) {
1160 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); 1166 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
1161 ASSERT(meta); 1167 ASSERT(meta);
1162 1168
@@ -1164,7 +1170,7 @@ private:
1164 GetSwizzle(meta->element); 1170 GetSwizzle(meta->element);
1165 } 1171 }
1166 1172
1167 std::string F4TextureQueryDimensions(Operation operation) { 1173 std::string TextureQueryDimensions(Operation operation) {
1168 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); 1174 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
1169 ASSERT(meta); 1175 ASSERT(meta);
1170 1176
@@ -1184,7 +1190,7 @@ private:
1184 return "0"; 1190 return "0";
1185 } 1191 }
1186 1192
1187 std::string F4TextureQueryLod(Operation operation) { 1193 std::string TextureQueryLod(Operation operation) {
1188 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); 1194 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
1189 ASSERT(meta); 1195 ASSERT(meta);
1190 1196
@@ -1195,29 +1201,32 @@ private:
1195 return "0"; 1201 return "0";
1196 } 1202 }
1197 1203
1198 std::string F4TexelFetch(Operation operation) { 1204 std::string TexelFetch(Operation operation) {
1199 constexpr std::array<const char*, 4> constructors = {"int", "ivec2", "ivec3", "ivec4"}; 1205 constexpr std::array<const char*, 4> constructors = {"int", "ivec2", "ivec3", "ivec4"};
1200 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); 1206 const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
1201 const auto count = static_cast<u32>(operation.GetOperandsCount());
1202 ASSERT(meta); 1207 ASSERT(meta);
1208 UNIMPLEMENTED_IF(meta->sampler.IsArray());
1209 UNIMPLEMENTED_IF(!meta->extras.empty());
1210
1211 const auto count = static_cast<u32>(operation.GetOperandsCount());
1203 1212
1204 std::string expr = "texelFetch("; 1213 std::string expr = "texelFetch(";
1205 expr += GetSampler(meta->sampler); 1214 expr += GetSampler(meta->sampler);
1206 expr += ", "; 1215 expr += ", ";
1207 1216
1208 expr += constructors[meta->coords_count - 1]; 1217 expr += constructors.at(count - 1);
1209 expr += '('; 1218 expr += '(';
1210 for (u32 i = 0; i < count; ++i) { 1219 for (u32 i = 0; i < count; ++i) {
1211 expr += VisitOperand(operation, i, Type::Int); 1220 expr += VisitOperand(operation, i, Type::Int);
1212 1221
1213 if (i + 1 == meta->coords_count) { 1222 const u32 next = i + 1;
1223 if (next == count)
1214 expr += ')'; 1224 expr += ')';
1215 } 1225 if (next < count)
1216 if (i + 1 < count) {
1217 expr += ", "; 1226 expr += ", ";
1218 }
1219 } 1227 }
1220 expr += ')'; 1228 expr += ')';
1229
1221 return expr + GetSwizzle(meta->element); 1230 return expr + GetSwizzle(meta->element);
1222 } 1231 }
1223 1232
@@ -1454,12 +1463,12 @@ private:
1454 &GLSLDecompiler::Logical2HNotEqual, 1463 &GLSLDecompiler::Logical2HNotEqual,
1455 &GLSLDecompiler::Logical2HGreaterEqual, 1464 &GLSLDecompiler::Logical2HGreaterEqual,
1456 1465
1457 &GLSLDecompiler::F4Texture, 1466 &GLSLDecompiler::Texture,
1458 &GLSLDecompiler::F4TextureLod, 1467 &GLSLDecompiler::TextureLod,
1459 &GLSLDecompiler::F4TextureGather, 1468 &GLSLDecompiler::TextureGather,
1460 &GLSLDecompiler::F4TextureQueryDimensions, 1469 &GLSLDecompiler::TextureQueryDimensions,
1461 &GLSLDecompiler::F4TextureQueryLod, 1470 &GLSLDecompiler::TextureQueryLod,
1462 &GLSLDecompiler::F4TexelFetch, 1471 &GLSLDecompiler::TexelFetch,
1463 1472
1464 &GLSLDecompiler::Branch, 1473 &GLSLDecompiler::Branch,
1465 &GLSLDecompiler::PushFlowStack, 1474 &GLSLDecompiler::PushFlowStack,
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 6476a9e1a..cca2ed708 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -107,7 +107,7 @@ RendererOpenGL::~RendererOpenGL() = default;
107void RendererOpenGL::SwapBuffers( 107void RendererOpenGL::SwapBuffers(
108 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) { 108 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) {
109 109
110 Core::System::GetInstance().GetPerfStats().EndSystemFrame(); 110 system.GetPerfStats().EndSystemFrame();
111 111
112 // Maintain the rasterizer's state as a priority 112 // Maintain the rasterizer's state as a priority
113 OpenGLState prev_state = OpenGLState::GetCurState(); 113 OpenGLState prev_state = OpenGLState::GetCurState();
@@ -137,8 +137,8 @@ void RendererOpenGL::SwapBuffers(
137 137
138 render_window.PollEvents(); 138 render_window.PollEvents();
139 139
140 Core::System::GetInstance().FrameLimiter().DoFrameLimiting(CoreTiming::GetGlobalTimeUs()); 140 system.FrameLimiter().DoFrameLimiting(Core::Timing::GetGlobalTimeUs());
141 Core::System::GetInstance().GetPerfStats().BeginSystemFrame(); 141 system.GetPerfStats().BeginSystemFrame();
142 142
143 // Restore the rasterizer state 143 // Restore the rasterizer state
144 prev_state.Apply(); 144 prev_state.Apply();
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index 38bb692d6..9fd4b273e 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer.cpp
@@ -41,7 +41,7 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
41 41
42 const Node value = Operation(OperationCode::IAdd, PRECISE, op_a, op_b); 42 const Node value = Operation(OperationCode::IAdd, PRECISE, op_a, op_b);
43 43
44 SetInternalFlagsFromInteger(bb, value, instr.op_32.generates_cc); 44 SetInternalFlagsFromInteger(bb, value, instr.generates_cc);
45 SetRegister(bb, instr.gpr0, value); 45 SetRegister(bb, instr.gpr0, value);
46 break; 46 break;
47 } 47 }
@@ -284,4 +284,4 @@ void ShaderIR::WriteLop3Instruction(NodeBlock& bb, Register dest, Node op_a, Nod
284 SetRegister(bb, dest, value); 284 SetRegister(bb, dest, value);
285} 285}
286 286
287} // namespace VideoCommon::Shader \ No newline at end of file 287} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp
index a992f73f8..55a6fbbf2 100644
--- a/src/video_core/shader/decode/conversion.cpp
+++ b/src/video_core/shader/decode/conversion.cpp
@@ -118,8 +118,8 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
118 118
119 value = [&]() { 119 value = [&]() {
120 switch (instr.conversion.f2i.rounding) { 120 switch (instr.conversion.f2i.rounding) {
121 case Tegra::Shader::F2iRoundingOp::None: 121 case Tegra::Shader::F2iRoundingOp::RoundEven:
122 return value; 122 return Operation(OperationCode::FRoundEven, PRECISE, value);
123 case Tegra::Shader::F2iRoundingOp::Floor: 123 case Tegra::Shader::F2iRoundingOp::Floor:
124 return Operation(OperationCode::FFloor, PRECISE, value); 124 return Operation(OperationCode::FFloor, PRECISE, value);
125 case Tegra::Shader::F2iRoundingOp::Ceil: 125 case Tegra::Shader::F2iRoundingOp::Ceil:
@@ -146,4 +146,4 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
146 return pc; 146 return pc;
147} 147}
148 148
149} // namespace VideoCommon::Shader \ No newline at end of file 149} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index e006f8138..523421794 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -306,7 +306,6 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
306 case OpCode::Id::TLD4S: { 306 case OpCode::Id::TLD4S: {
307 UNIMPLEMENTED_IF_MSG(instr.tld4s.UsesMiscMode(TextureMiscMode::AOFFI), 307 UNIMPLEMENTED_IF_MSG(instr.tld4s.UsesMiscMode(TextureMiscMode::AOFFI),
308 "AOFFI is not implemented"); 308 "AOFFI is not implemented");
309
310 if (instr.tld4s.UsesMiscMode(TextureMiscMode::NODEP)) { 309 if (instr.tld4s.UsesMiscMode(TextureMiscMode::NODEP)) {
311 LOG_WARNING(HW_GPU, "TLD4S.NODEP implementation is incomplete"); 310 LOG_WARNING(HW_GPU, "TLD4S.NODEP implementation is incomplete");
312 } 311 }
@@ -315,9 +314,8 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
315 const Node op_a = GetRegister(instr.gpr8); 314 const Node op_a = GetRegister(instr.gpr8);
316 const Node op_b = GetRegister(instr.gpr20); 315 const Node op_b = GetRegister(instr.gpr20);
317 316
318 std::vector<Node> coords;
319
320 // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction. 317 // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction.
318 std::vector<Node> coords;
321 if (depth_compare) { 319 if (depth_compare) {
322 // Note: TLD4S coordinate encoding works just like TEXS's 320 // Note: TLD4S coordinate encoding works just like TEXS's
323 const Node op_y = GetRegister(instr.gpr8.Value() + 1); 321 const Node op_y = GetRegister(instr.gpr8.Value() + 1);
@@ -328,18 +326,17 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
328 coords.push_back(op_a); 326 coords.push_back(op_a);
329 coords.push_back(op_b); 327 coords.push_back(op_b);
330 } 328 }
331 const auto num_coords = static_cast<u32>(coords.size()); 329 std::vector<Node> extras;
332 coords.push_back(Immediate(static_cast<u32>(instr.tld4s.component))); 330 extras.push_back(Immediate(static_cast<u32>(instr.tld4s.component)));
333 331
334 const auto& sampler = 332 const auto& sampler =
335 GetSampler(instr.sampler, TextureType::Texture2D, false, depth_compare); 333 GetSampler(instr.sampler, TextureType::Texture2D, false, depth_compare);
336 334
337 Node4 values; 335 Node4 values;
338 for (u32 element = 0; element < values.size(); ++element) { 336 for (u32 element = 0; element < values.size(); ++element) {
339 auto params = coords; 337 auto coords_copy = coords;
340 MetaTexture meta{sampler, element, num_coords}; 338 MetaTexture meta{sampler, {}, {}, extras, element};
341 values[element] = 339 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
342 Operation(OperationCode::F4TextureGather, std::move(meta), std::move(params));
343 } 340 }
344 341
345 WriteTexsInstructionFloat(bb, instr, values); 342 WriteTexsInstructionFloat(bb, instr, values);
@@ -360,12 +357,13 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
360 switch (instr.txq.query_type) { 357 switch (instr.txq.query_type) {
361 case Tegra::Shader::TextureQueryType::Dimension: { 358 case Tegra::Shader::TextureQueryType::Dimension: {
362 for (u32 element = 0; element < 4; ++element) { 359 for (u32 element = 0; element < 4; ++element) {
363 if (instr.txq.IsComponentEnabled(element)) { 360 if (!instr.txq.IsComponentEnabled(element)) {
364 MetaTexture meta{sampler, element}; 361 continue;
365 const Node value = Operation(OperationCode::F4TextureQueryDimensions,
366 std::move(meta), GetRegister(instr.gpr8));
367 SetTemporal(bb, indexer++, value);
368 } 362 }
363 MetaTexture meta{sampler, {}, {}, {}, element};
364 const Node value =
365 Operation(OperationCode::TextureQueryDimensions, meta, GetRegister(instr.gpr8));
366 SetTemporal(bb, indexer++, value);
369 } 367 }
370 for (u32 i = 0; i < indexer; ++i) { 368 for (u32 i = 0; i < indexer; ++i) {
371 SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); 369 SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i));
@@ -412,9 +410,8 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
412 410
413 for (u32 element = 0; element < 2; ++element) { 411 for (u32 element = 0; element < 2; ++element) {
414 auto params = coords; 412 auto params = coords;
415 MetaTexture meta_texture{sampler, element, static_cast<u32>(coords.size())}; 413 MetaTexture meta{sampler, {}, {}, {}, element};
416 const Node value = 414 const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
417 Operation(OperationCode::F4TextureQueryLod, meta_texture, std::move(params));
418 SetTemporal(bb, element, value); 415 SetTemporal(bb, element, value);
419 } 416 }
420 for (u32 element = 0; element < 2; ++element) { 417 for (u32 element = 0; element < 2; ++element) {
@@ -535,15 +532,16 @@ void ShaderIR::WriteTexsInstructionHalfFloat(NodeBlock& bb, Instruction instr,
535} 532}
536 533
537Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, 534Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
538 TextureProcessMode process_mode, bool depth_compare, bool is_array, 535 TextureProcessMode process_mode, std::vector<Node> coords,
539 std::size_t array_offset, std::size_t bias_offset, 536 Node array, Node depth_compare, u32 bias_offset) {
540 std::vector<Node>&& coords) { 537 const bool is_array = array;
541 UNIMPLEMENTED_IF_MSG( 538 const bool is_shadow = depth_compare;
542 (texture_type == TextureType::Texture3D && (is_array || depth_compare)) ||
543 (texture_type == TextureType::TextureCube && is_array && depth_compare),
544 "This method is not supported.");
545 539
546 const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, depth_compare); 540 UNIMPLEMENTED_IF_MSG((texture_type == TextureType::Texture3D && (is_array || is_shadow)) ||
541 (texture_type == TextureType::TextureCube && is_array && is_shadow),
542 "This method is not supported.");
543
544 const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, is_shadow);
547 545
548 const bool lod_needed = process_mode == TextureProcessMode::LZ || 546 const bool lod_needed = process_mode == TextureProcessMode::LZ ||
549 process_mode == TextureProcessMode::LL || 547 process_mode == TextureProcessMode::LL ||
@@ -552,35 +550,30 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
552 // LOD selection (either via bias or explicit textureLod) not supported in GL for 550 // LOD selection (either via bias or explicit textureLod) not supported in GL for
553 // sampler2DArrayShadow and samplerCubeArrayShadow. 551 // sampler2DArrayShadow and samplerCubeArrayShadow.
554 const bool gl_lod_supported = 552 const bool gl_lod_supported =
555 !((texture_type == Tegra::Shader::TextureType::Texture2D && is_array && depth_compare) || 553 !((texture_type == Tegra::Shader::TextureType::Texture2D && is_array && is_shadow) ||
556 (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && depth_compare)); 554 (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow));
557 555
558 const OperationCode read_method = 556 const OperationCode read_method =
559 lod_needed && gl_lod_supported ? OperationCode::F4TextureLod : OperationCode::F4Texture; 557 lod_needed && gl_lod_supported ? OperationCode::TextureLod : OperationCode::Texture;
560 558
561 UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported); 559 UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported);
562 560
563 std::optional<u32> array_offset_value; 561 std::vector<Node> extras;
564 if (is_array)
565 array_offset_value = static_cast<u32>(array_offset);
566
567 const auto coords_count = static_cast<u32>(coords.size());
568
569 if (process_mode != TextureProcessMode::None && gl_lod_supported) { 562 if (process_mode != TextureProcessMode::None && gl_lod_supported) {
570 if (process_mode == TextureProcessMode::LZ) { 563 if (process_mode == TextureProcessMode::LZ) {
571 coords.push_back(Immediate(0.0f)); 564 extras.push_back(Immediate(0.0f));
572 } else { 565 } else {
573 // If present, lod or bias are always stored in the register indexed by the gpr20 566 // If present, lod or bias are always stored in the register indexed by the gpr20
574 // field with an offset depending on the usage of the other registers 567 // field with an offset depending on the usage of the other registers
575 coords.push_back(GetRegister(instr.gpr20.Value() + bias_offset)); 568 extras.push_back(GetRegister(instr.gpr20.Value() + bias_offset));
576 } 569 }
577 } 570 }
578 571
579 Node4 values; 572 Node4 values;
580 for (u32 element = 0; element < values.size(); ++element) { 573 for (u32 element = 0; element < values.size(); ++element) {
581 auto params = coords; 574 auto copy_coords = coords;
582 MetaTexture meta{sampler, element, coords_count, array_offset_value}; 575 MetaTexture meta{sampler, array, depth_compare, extras, element};
583 values[element] = Operation(read_method, std::move(meta), std::move(params)); 576 values[element] = Operation(read_method, meta, std::move(copy_coords));
584 } 577 }
585 578
586 return values; 579 return values;
@@ -602,28 +595,22 @@ Node4 ShaderIR::GetTexCode(Instruction instr, TextureType texture_type,
602 for (std::size_t i = 0; i < coord_count; ++i) { 595 for (std::size_t i = 0; i < coord_count; ++i) {
603 coords.push_back(GetRegister(coord_register + i)); 596 coords.push_back(GetRegister(coord_register + i));
604 } 597 }
605 // 1D.DC in opengl the 2nd component is ignored. 598 // 1D.DC in OpenGL the 2nd component is ignored.
606 if (depth_compare && !is_array && texture_type == TextureType::Texture1D) { 599 if (depth_compare && !is_array && texture_type == TextureType::Texture1D) {
607 coords.push_back(Immediate(0.0f)); 600 coords.push_back(Immediate(0.0f));
608 } 601 }
609 std::size_t array_offset{}; 602
610 if (is_array) { 603 const Node array = is_array ? GetRegister(array_register) : nullptr;
611 array_offset = coords.size(); 604
612 coords.push_back(GetRegister(array_register)); 605 Node dc{};
613 }
614 if (depth_compare) { 606 if (depth_compare) {
615 // Depth is always stored in the register signaled by gpr20 607 // Depth is always stored in the register signaled by gpr20 or in the next register if lod
616 // or in the next register if lod or bias are used 608 // or bias are used
617 const u64 depth_register = instr.gpr20.Value() + (lod_bias_enabled ? 1 : 0); 609 const u64 depth_register = instr.gpr20.Value() + (lod_bias_enabled ? 1 : 0);
618 coords.push_back(GetRegister(depth_register)); 610 dc = GetRegister(depth_register);
619 }
620 // Fill ignored coordinates
621 while (coords.size() < total_coord_count) {
622 coords.push_back(Immediate(0));
623 } 611 }
624 612
625 return GetTextureCode(instr, texture_type, process_mode, depth_compare, is_array, array_offset, 613 return GetTextureCode(instr, texture_type, process_mode, coords, array, dc, 0);
626 0, std::move(coords));
627} 614}
628 615
629Node4 ShaderIR::GetTexsCode(Instruction instr, TextureType texture_type, 616Node4 ShaderIR::GetTexsCode(Instruction instr, TextureType texture_type,
@@ -641,6 +628,7 @@ Node4 ShaderIR::GetTexsCode(Instruction instr, TextureType texture_type,
641 (is_array || !(lod_bias_enabled || depth_compare) || (coord_count > 2)) 628 (is_array || !(lod_bias_enabled || depth_compare) || (coord_count > 2))
642 ? static_cast<u64>(instr.gpr20.Value()) 629 ? static_cast<u64>(instr.gpr20.Value())
643 : coord_register + 1; 630 : coord_register + 1;
631 const u32 bias_offset = coord_count > 2 ? 1 : 0;
644 632
645 std::vector<Node> coords; 633 std::vector<Node> coords;
646 for (std::size_t i = 0; i < coord_count; ++i) { 634 for (std::size_t i = 0; i < coord_count; ++i) {
@@ -648,24 +636,17 @@ Node4 ShaderIR::GetTexsCode(Instruction instr, TextureType texture_type,
648 coords.push_back(GetRegister(last ? last_coord_register : coord_register + i)); 636 coords.push_back(GetRegister(last ? last_coord_register : coord_register + i));
649 } 637 }
650 638
651 std::size_t array_offset{}; 639 const Node array = is_array ? GetRegister(array_register) : nullptr;
652 if (is_array) { 640
653 array_offset = coords.size(); 641 Node dc{};
654 coords.push_back(GetRegister(array_register));
655 }
656 if (depth_compare) { 642 if (depth_compare) {
657 // Depth is always stored in the register signaled by gpr20 643 // Depth is always stored in the register signaled by gpr20 or in the next register if lod
658 // or in the next register if lod or bias are used 644 // or bias are used
659 const u64 depth_register = instr.gpr20.Value() + (lod_bias_enabled ? 1 : 0); 645 const u64 depth_register = instr.gpr20.Value() + (lod_bias_enabled ? 1 : 0);
660 coords.push_back(GetRegister(depth_register)); 646 dc = GetRegister(depth_register);
661 }
662 // Fill ignored coordinates
663 while (coords.size() < total_coord_count) {
664 coords.push_back(Immediate(0));
665 } 647 }
666 648
667 return GetTextureCode(instr, texture_type, process_mode, depth_compare, is_array, array_offset, 649 return GetTextureCode(instr, texture_type, process_mode, coords, array, dc, bias_offset);
668 (coord_count > 2 ? 1 : 0), std::move(coords));
669} 650}
670 651
671Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool depth_compare, 652Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool depth_compare,
@@ -680,24 +661,16 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
680 const u64 coord_register = array_register + (is_array ? 1 : 0); 661 const u64 coord_register = array_register + (is_array ? 1 : 0);
681 662
682 std::vector<Node> coords; 663 std::vector<Node> coords;
683 664 for (size_t i = 0; i < coord_count; ++i)
684 for (size_t i = 0; i < coord_count; ++i) {
685 coords.push_back(GetRegister(coord_register + i)); 665 coords.push_back(GetRegister(coord_register + i));
686 }
687 std::optional<u32> array_offset;
688 if (is_array) {
689 array_offset = static_cast<u32>(coords.size());
690 coords.push_back(GetRegister(array_register));
691 }
692 666
693 const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, depth_compare); 667 const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, depth_compare);
694 668
695 Node4 values; 669 Node4 values;
696 for (u32 element = 0; element < values.size(); ++element) { 670 for (u32 element = 0; element < values.size(); ++element) {
697 auto params = coords; 671 auto coords_copy = coords;
698 MetaTexture meta{sampler, element, static_cast<u32>(coords.size()), array_offset}; 672 MetaTexture meta{sampler, GetRegister(array_register), {}, {}, element};
699 values[element] = 673 values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
700 Operation(OperationCode::F4TextureGather, std::move(meta), std::move(params));
701 } 674 }
702 675
703 return values; 676 return values;
@@ -705,7 +678,6 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
705 678
706Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is_array) { 679Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is_array) {
707 const std::size_t type_coord_count = GetCoordCount(texture_type); 680 const std::size_t type_coord_count = GetCoordCount(texture_type);
708 const std::size_t total_coord_count = type_coord_count + (is_array ? 1 : 0);
709 const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL; 681 const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL;
710 682
711 // If enabled arrays index is always stored in the gpr8 field 683 // If enabled arrays index is always stored in the gpr8 field
@@ -719,33 +691,22 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
719 : coord_register + 1; 691 : coord_register + 1;
720 692
721 std::vector<Node> coords; 693 std::vector<Node> coords;
722
723 for (std::size_t i = 0; i < type_coord_count; ++i) { 694 for (std::size_t i = 0; i < type_coord_count; ++i) {
724 const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1); 695 const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1);
725 coords.push_back(GetRegister(last ? last_coord_register : coord_register + i)); 696 coords.push_back(GetRegister(last ? last_coord_register : coord_register + i));
726 } 697 }
727 std::optional<u32> array_offset;
728 if (is_array) {
729 array_offset = static_cast<u32>(coords.size());
730 coords.push_back(GetRegister(array_register));
731 }
732 const auto coords_count = static_cast<u32>(coords.size());
733 698
734 if (lod_enabled) { 699 const Node array = is_array ? GetRegister(array_register) : nullptr;
735 // When lod is used always is in grp20 700 // When lod is used always is in gpr20
736 coords.push_back(GetRegister(instr.gpr20)); 701 const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0);
737 } else {
738 coords.push_back(Immediate(0));
739 }
740 702
741 const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, false); 703 const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, false);
742 704
743 Node4 values; 705 Node4 values;
744 for (u32 element = 0; element < values.size(); ++element) { 706 for (u32 element = 0; element < values.size(); ++element) {
745 auto params = coords; 707 auto coords_copy = coords;
746 MetaTexture meta{sampler, element, coords_count, array_offset}; 708 MetaTexture meta{sampler, array, {}, {lod}, element};
747 values[element] = 709 values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
748 Operation(OperationCode::F4TexelFetch, std::move(meta), std::move(params));
749 } 710 }
750 return values; 711 return values;
751} 712}
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 1d4fbef53..52c7f2c4e 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -156,12 +156,12 @@ enum class OperationCode {
156 Logical2HNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 156 Logical2HNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
157 Logical2HGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 157 Logical2HGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
158 158
159 F4Texture, /// (MetaTexture, float[N] coords, float[M] params) -> float4 159 Texture, /// (MetaTexture, float[N] coords) -> float4
160 F4TextureLod, /// (MetaTexture, float[N] coords, float[M] params) -> float4 160 TextureLod, /// (MetaTexture, float[N] coords) -> float4
161 F4TextureGather, /// (MetaTexture, float[N] coords, float[M] params) -> float4 161 TextureGather, /// (MetaTexture, float[N] coords) -> float4
162 F4TextureQueryDimensions, /// (MetaTexture, float a) -> float4 162 TextureQueryDimensions, /// (MetaTexture, float a) -> float4
163 F4TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4 163 TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4
164 F4TexelFetch, /// (MetaTexture, int[N], int) -> float4 164 TexelFetch, /// (MetaTexture, int[N], int) -> float4
165 165
166 Branch, /// (uint branch_target) -> void 166 Branch, /// (uint branch_target) -> void
167 PushFlowStack, /// (uint branch_target) -> void 167 PushFlowStack, /// (uint branch_target) -> void
@@ -288,9 +288,10 @@ struct MetaHalfArithmetic {
288 288
289struct MetaTexture { 289struct MetaTexture {
290 const Sampler& sampler; 290 const Sampler& sampler;
291 Node array{};
292 Node depth_compare{};
293 std::vector<Node> extras;
291 u32 element{}; 294 u32 element{};
292 u32 coords_count{};
293 std::optional<u32> array_index;
294}; 295};
295 296
296constexpr MetaArithmetic PRECISE = {true}; 297constexpr MetaArithmetic PRECISE = {true};
@@ -754,9 +755,8 @@ private:
754 bool lod_bias_enabled, std::size_t max_coords, std::size_t max_inputs); 755 bool lod_bias_enabled, std::size_t max_coords, std::size_t max_inputs);
755 756
756 Node4 GetTextureCode(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type, 757 Node4 GetTextureCode(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type,
757 Tegra::Shader::TextureProcessMode process_mode, bool depth_compare, 758 Tegra::Shader::TextureProcessMode process_mode, std::vector<Node> coords,
758 bool is_array, std::size_t array_offset, std::size_t bias_offset, 759 Node array, Node depth_compare, u32 bias_offset);
759 std::vector<Node>&& coords);
760 760
761 Node GetVideoOperand(Node op, bool is_chunk, bool is_signed, Tegra::Shader::VideoType type, 761 Node GetVideoOperand(Node op, bool is_chunk, bool is_signed, Tegra::Shader::VideoType type,
762 u64 byte_height); 762 u64 byte_height);