summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
: sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
sink_stream{sink_stream}, name{std::move(name_)} {
- release_event = CoreTiming::RegisterEvent(
+ release_event = Core::Timing::RegisterEvent(
name, [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); });
}
@@ -57,7 +57,7 @@ Stream::State Stream::GetState() const {
s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
const std::size_t num_samples{buffer.GetSamples().size() / GetNumChannels()};
- return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
+ return Core::Timing::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
}
static void VolumeAdjustSamples(std::vector<s16>& samples) {
@@ -99,7 +99,8 @@ void Stream::PlayNextBuffer() {
sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples());
- CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {});
+ Core::Timing::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event,
+ {});
}
void 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 @@
#include "audio_core/buffer.h"
#include "common/common_types.h"
-namespace CoreTiming {
+namespace Core::Timing {
struct EventType;
}
@@ -91,16 +91,16 @@ private:
/// Gets the number of core cycles when the specified buffer will be released
s64 GetBufferReleaseCycles(const Buffer& buffer) const;
- u32 sample_rate; ///< Sample rate of the stream
- Format format; ///< Format of the stream
- ReleaseCallback release_callback; ///< Buffer release callback for the stream
- State state{State::Stopped}; ///< Playback state of the stream
- CoreTiming::EventType* release_event{}; ///< Core timing release event for the stream
- BufferPtr active_buffer; ///< Actively playing buffer in the stream
- std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream
- std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream
- SinkStream& sink_stream; ///< Output sink for the stream
- std::string name; ///< Name of the stream, must be unique
+ u32 sample_rate; ///< Sample rate of the stream
+ Format format; ///< Format of the stream
+ ReleaseCallback release_callback; ///< Buffer release callback for the stream
+ State state{State::Stopped}; ///< Playback state of the stream
+ Core::Timing::EventType* release_event{}; ///< Core timing release event for the stream
+ BufferPtr active_buffer; ///< Actively playing buffer in the stream
+ std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream
+ std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream
+ SinkStream& sink_stream; ///< Output sink for the stream
+ std::string name; ///< Name of the stream, must be unique
};
using 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:
// Always execute at least one tick.
amortized_ticks = std::max<u64>(amortized_ticks, 1);
- CoreTiming::AddTicks(amortized_ticks);
+ Timing::AddTicks(amortized_ticks);
num_interpreted_instructions = 0;
}
u64 GetTicksRemaining() override {
- return std::max(CoreTiming::GetDowncount(), 0);
+ return std::max(Timing::GetDowncount(), 0);
}
u64 GetCNTPCT() override {
- return CoreTiming::GetTicks();
+ return Timing::GetTicks();
}
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() {
if (GDBStub::IsServerEnabled()) {
ExecuteInstructions(std::max(4000000, 0));
} else {
- ExecuteInstructions(std::max(CoreTiming::GetDowncount(), 0));
+ ExecuteInstructions(std::max(Timing::GetDowncount(), 0));
}
}
@@ -190,7 +190,7 @@ MICROPROFILE_DEFINE(ARM_Jit_Unicorn, "ARM JIT", "Unicorn", MP_RGB(255, 64, 64));
void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
MICROPROFILE_SCOPE(ARM_Jit_Unicorn);
CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions));
- CoreTiming::AddTicks(num_instructions);
+ Timing::AddTicks(num_instructions);
if (GDBStub::IsServerEnabled()) {
if (last_bkpt_hit) {
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 {
ResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
LOG_DEBUG(HW_Memory, "initialized OK");
- CoreTiming::Init();
+ Timing::Init();
kernel.Initialize();
const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
@@ -205,7 +205,7 @@ struct System::Impl {
// Shutdown kernel and core timing
kernel.Shutdown();
- CoreTiming::Shutdown();
+ Timing::Shutdown();
// Close app loader
app_loader.reset();
@@ -232,7 +232,7 @@ struct System::Impl {
}
PerfStatsResults GetAndResetPerfStats() {
- return perf_stats.GetAndResetStats(CoreTiming::GetGlobalTimeUs());
+ return perf_stats.GetAndResetStats(Timing::GetGlobalTimeUs());
}
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) {
if (IsMainCore()) {
// TODO(Subv): Only let CoreTiming idle if all 4 cores are idling.
- CoreTiming::Idle();
- CoreTiming::Advance();
+ Timing::Idle();
+ Timing::Advance();
}
PrepareReschedule();
} else {
if (IsMainCore()) {
- CoreTiming::Advance();
+ Timing::Advance();
}
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 @@
#include "common/threadsafe_queue.h"
#include "core/core_timing_util.h"
-namespace CoreTiming {
+namespace Core::Timing {
static s64 global_timer;
static int slice_length;
@@ -242,4 +242,4 @@ int GetDowncount() {
return downcount;
}
-} // namespace CoreTiming
+} // 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 @@
#include <string>
#include "common/common_types.h"
-namespace CoreTiming {
+namespace Core::Timing {
struct EventType;
@@ -92,4 +92,4 @@ std::chrono::microseconds GetGlobalTimeUs();
int GetDowncount();
-} // namespace CoreTiming
+} // 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 @@
#include <limits>
#include "common/logging/log.h"
-namespace CoreTiming {
+namespace Core::Timing {
constexpr u64 MAX_VALUE_TO_MULTIPLY = std::numeric_limits<s64>::max() / BASE_CLOCK_RATE;
@@ -60,4 +60,4 @@ s64 nsToCycles(u64 ns) {
return (BASE_CLOCK_RATE * static_cast<s64>(ns)) / 1000000000;
}
-} // namespace CoreTiming
+} // 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 @@
#include "common/common_types.h"
-namespace CoreTiming {
+namespace Core::Timing {
// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz
// The exact value used is of course unverified.
@@ -61,4 +61,4 @@ inline u64 cyclesToMs(s64 cycles) {
return cycles * 1000 / BASE_CLOCK_RATE;
}
-} // namespace CoreTiming
+} // 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 {
void InitializeThreads() {
thread_wakeup_event_type =
- CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
+ Core::Timing::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
}
std::atomic<u32> next_object_id{0};
@@ -137,7 +137,7 @@ struct KernelCore::Impl {
SharedPtr<ResourceLimit> system_resource_limit;
- CoreTiming::EventType* thread_wakeup_event_type = nullptr;
+ Core::Timing::EventType* thread_wakeup_event_type = nullptr;
// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future,
// allowing us to simply use a pool index or similar.
Kernel::HandleTable thread_wakeup_callback_handle_table;
@@ -213,7 +213,7 @@ u64 KernelCore::CreateNewProcessID() {
return impl->next_process_id++;
}
-CoreTiming::EventType* KernelCore::ThreadWakeupCallbackEventType() const {
+Core::Timing::EventType* KernelCore::ThreadWakeupCallbackEventType() const {
return impl->thread_wakeup_event_type;
}
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 @@
template <typename T>
class ResultVal;
-namespace CoreTiming {
+namespace Core::Timing {
struct EventType;
}
@@ -89,7 +89,7 @@ private:
u64 CreateNewThreadID();
/// Retrieves the event type used for thread wakeup callbacks.
- CoreTiming::EventType* ThreadWakeupCallbackEventType() const;
+ Core::Timing::EventType* ThreadWakeupCallbackEventType() const;
/// Provides a reference to the thread wakeup callback handle table.
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) {
void Scheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) {
const u64 prev_switch_ticks = last_context_switch_time;
- const u64 most_recent_switch_ticks = CoreTiming::GetTicks();
+ const u64 most_recent_switch_ticks = Core::Timing::GetTicks();
const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks;
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)
if (same_thread && info_sub_id == 0xFFFFFFFFFFFFFFFF) {
const u64 thread_ticks = current_thread->GetTotalCPUTimeTicks();
- out_ticks = thread_ticks + (CoreTiming::GetTicks() - prev_ctx_ticks);
+ out_ticks = thread_ticks + (Core::Timing::GetTicks() - prev_ctx_ticks);
} else if (same_thread && info_sub_id == system.CurrentCoreIndex()) {
- out_ticks = CoreTiming::GetTicks() - prev_ctx_ticks;
+ out_ticks = Core::Timing::GetTicks() - prev_ctx_ticks;
}
*result = out_ticks;
@@ -1546,10 +1546,10 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to
static u64 GetSystemTick() {
LOG_TRACE(Kernel_SVC, "called");
- const u64 result{CoreTiming::GetTicks()};
+ const u64 result{Core::Timing::GetTicks()};
// Advance time to defeat dumb games that busy-wait for the frame to end.
- CoreTiming::AddTicks(400);
+ Core::Timing::AddTicks(400);
return result;
}
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;
void Thread::Stop() {
// Cancel any outstanding wakeup events for this thread
- CoreTiming::UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), callback_handle);
+ Core::Timing::UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), callback_handle);
kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle);
callback_handle = 0;
@@ -85,12 +85,13 @@ void Thread::WakeAfterDelay(s64 nanoseconds) {
// This function might be called from any thread so we have to be cautious and use the
// thread-safe version of ScheduleEvent.
- CoreTiming::ScheduleEventThreadsafe(CoreTiming::nsToCycles(nanoseconds),
- kernel.ThreadWakeupCallbackEventType(), callback_handle);
+ Core::Timing::ScheduleEventThreadsafe(Core::Timing::nsToCycles(nanoseconds),
+ kernel.ThreadWakeupCallbackEventType(), callback_handle);
}
void Thread::CancelWakeupTimer() {
- CoreTiming::UnscheduleEventThreadsafe(kernel.ThreadWakeupCallbackEventType(), callback_handle);
+ Core::Timing::UnscheduleEventThreadsafe(kernel.ThreadWakeupCallbackEventType(),
+ callback_handle);
}
static std::optional<s32> GetNextProcessorId(u64 mask) {
@@ -197,7 +198,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
thread->stack_top = stack_top;
thread->tpidr_el0 = 0;
thread->nominal_priority = thread->current_priority = priority;
- thread->last_running_ticks = CoreTiming::GetTicks();
+ thread->last_running_ticks = Core::Timing::GetTicks();
thread->processor_id = processor_id;
thread->ideal_core = processor_id;
thread->affinity_mask = 1ULL << processor_id;
@@ -257,7 +258,7 @@ void Thread::SetStatus(ThreadStatus new_status) {
}
if (status == ThreadStatus::Running) {
- last_running_ticks = CoreTiming::GetTicks();
+ last_running_ticks = Core::Timing::GetTicks();
}
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() {}
void Controller_DebugPad::OnRelease() {}
void Controller_DebugPad::OnUpdate(u8* data, std::size_t size) {
- shared_memory.header.timestamp = CoreTiming::GetTicks();
+ shared_memory.header.timestamp = Core::Timing::GetTicks();
shared_memory.header.total_entry_count = 17;
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() {}
void Controller_Gesture::OnRelease() {}
void Controller_Gesture::OnUpdate(u8* data, std::size_t size) {
- shared_memory.header.timestamp = CoreTiming::GetTicks();
+ shared_memory.header.timestamp = Core::Timing::GetTicks();
shared_memory.header.total_entry_count = 17;
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() {}
void Controller_Keyboard::OnRelease() {}
void Controller_Keyboard::OnUpdate(u8* data, std::size_t size) {
- shared_memory.header.timestamp = CoreTiming::GetTicks();
+ shared_memory.header.timestamp = Core::Timing::GetTicks();
shared_memory.header.total_entry_count = 17;
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() {}
void Controller_Mouse::OnRelease() {}
void Controller_Mouse::OnUpdate(u8* data, std::size_t size) {
- shared_memory.header.timestamp = CoreTiming::GetTicks();
+ shared_memory.header.timestamp = Core::Timing::GetTicks();
shared_memory.header.total_entry_count = 17;
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) {
const auto& last_entry =
main_controller->npad[main_controller->common.last_entry_index];
- main_controller->common.timestamp = CoreTiming::GetTicks();
+ main_controller->common.timestamp = Core::Timing::GetTicks();
main_controller->common.last_entry_index =
(main_controller->common.last_entry_index + 1) % 17;
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) {
}
CommonHeader header{};
- header.timestamp = CoreTiming::GetTicks();
+ header.timestamp = Core::Timing::GetTicks();
header.total_entry_count = 17;
header.entry_count = 0;
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() {}
void Controller_Touchscreen::OnRelease() {}
void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) {
- shared_memory.header.timestamp = CoreTiming::GetTicks();
+ shared_memory.header.timestamp = Core::Timing::GetTicks();
shared_memory.header.total_entry_count = 17;
if (!IsControllerActivated()) {
@@ -48,7 +48,7 @@ void Controller_Touchscreen::OnUpdate(u8* data, std::size_t size) {
touch_entry.diameter_x = Settings::values.touchscreen.diameter_x;
touch_entry.diameter_y = Settings::values.touchscreen.diameter_y;
touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle;
- const u64 tick = CoreTiming::GetTicks();
+ const u64 tick = Core::Timing::GetTicks();
touch_entry.delta_time = tick - last_touch;
last_touch = tick;
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() {}
void Controller_XPad::OnUpdate(u8* data, std::size_t size) {
for (auto& xpad_entry : shared_memory.shared_memory_entries) {
- xpad_entry.header.timestamp = CoreTiming::GetTicks();
+ xpad_entry.header.timestamp = Core::Timing::GetTicks();
xpad_entry.header.total_entry_count = 17;
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 {
// Updating period for each HID device.
// TODO(ogniK): Find actual polling rate of hid
-constexpr u64 pad_update_ticks = CoreTiming::BASE_CLOCK_RATE / 66;
-constexpr u64 accelerometer_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100;
-constexpr u64 gyroscope_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100;
+constexpr u64 pad_update_ticks = Core::Timing::BASE_CLOCK_RATE / 66;
+constexpr u64 accelerometer_update_ticks = Core::Timing::BASE_CLOCK_RATE / 100;
+constexpr u64 gyroscope_update_ticks = Core::Timing::BASE_CLOCK_RATE / 100;
constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") {
@@ -73,14 +73,13 @@ IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") {
GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000);
// Register update callbacks
- pad_update_event =
- CoreTiming::RegisterEvent("HID::UpdatePadCallback", [this](u64 userdata, int cycles_late) {
- UpdateControllers(userdata, cycles_late);
- });
+ pad_update_event = Core::Timing::RegisterEvent(
+ "HID::UpdatePadCallback",
+ [this](u64 userdata, int cycles_late) { UpdateControllers(userdata, cycles_late); });
// TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
- CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event);
+ Core::Timing::ScheduleEvent(pad_update_ticks, pad_update_event);
ReloadInputDevices();
}
@@ -94,7 +93,7 @@ void IAppletResource::DeactivateController(HidController controller) {
}
IAppletResource ::~IAppletResource() {
- CoreTiming::UnscheduleEvent(pad_update_event, 0);
+ Core::Timing::UnscheduleEvent(pad_update_event, 0);
}
void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
@@ -114,7 +113,7 @@ void IAppletResource::UpdateControllers(u64 userdata, int cycles_late) {
controller->OnUpdate(shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
}
- CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
+ Core::Timing::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
}
class 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 @@
#include "controllers/controller_base.h"
#include "core/hle/service/service.h"
-namespace CoreTiming {
+namespace Core::Timing {
struct EventType;
}
@@ -66,7 +66,7 @@ private:
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
- CoreTiming::EventType* pad_update_event;
+ Core::Timing::EventType* pad_update_event;
std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
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) {
IPC::ResponseBuilder rb{ctx, 5};
rb.Push(RESULT_SUCCESS);
- rb.PushRaw<u64>(CoreTiming::GetTicks());
+ rb.PushRaw<u64>(Core::Timing::GetTicks());
rb.PushRaw<u32>(0);
}
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
IoctlGetGpuTime params{};
std::memcpy(&params, input.data(), input.size());
- params.gpu_time = CoreTiming::cyclesToNs(CoreTiming::GetTicks());
+ params.gpu_time = Core::Timing::cyclesToNs(Core::Timing::GetTicks());
std::memcpy(output.data(), &params, output.size());
return 0;
}
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 @@
#include "core/hle/kernel/object.h"
#include "core/hle/kernel/writable_event.h"
-namespace CoreTiming {
-struct EventType;
-}
-
namespace Service::NVFlinger {
struct 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 @@
namespace Service::NVFlinger {
constexpr std::size_t SCREEN_REFRESH_RATE = 60;
-constexpr u64 frame_ticks = static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / SCREEN_REFRESH_RATE);
+constexpr u64 frame_ticks = static_cast<u64>(Core::Timing::BASE_CLOCK_RATE / SCREEN_REFRESH_RATE);
NVFlinger::NVFlinger() {
// Schedule the screen composition events
composition_event =
- CoreTiming::RegisterEvent("ScreenComposition", [this](u64 userdata, int cycles_late) {
+ Core::Timing::RegisterEvent("ScreenComposition", [this](u64 userdata, int cycles_late) {
Compose();
- CoreTiming::ScheduleEvent(frame_ticks - cycles_late, composition_event);
+ Core::Timing::ScheduleEvent(frame_ticks - cycles_late, composition_event);
});
- CoreTiming::ScheduleEvent(frame_ticks, composition_event);
+ Core::Timing::ScheduleEvent(frame_ticks, composition_event);
}
NVFlinger::~NVFlinger() {
- CoreTiming::UnscheduleEvent(composition_event, 0);
+ Core::Timing::UnscheduleEvent(composition_event, 0);
}
void 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 @@
#include "common/common_types.h"
#include "core/hle/kernel/object.h"
-namespace CoreTiming {
+namespace Core::Timing {
struct EventType;
}
@@ -115,8 +115,8 @@ private:
/// layers.
u32 next_buffer_queue_id = 1;
- /// CoreTiming event that handles screen composition.
- CoreTiming::EventType* composition_event;
+ /// Event that handles screen composition.
+ Core::Timing::EventType* composition_event;
};
} // 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:
void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Time, "called");
- SteadyClockTimePoint steady_clock_time_point{
- CoreTiming::cyclesToMs(CoreTiming::GetTicks()) / 1000};
+ const SteadyClockTimePoint steady_clock_time_point{
+ Core::Timing::cyclesToMs(Core::Timing::GetTicks()) / 1000};
IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2};
rb.Push(RESULT_SUCCESS);
rb.PushRaw(steady_clock_time_point);
@@ -282,7 +282,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
}
const SteadyClockTimePoint steady_clock_time_point{
- CoreTiming::cyclesToMs(CoreTiming::GetTicks()) / 1000, {}};
+ Core::Timing::cyclesToMs(Core::Timing::GetTicks()) / 1000, {}};
CalendarTime calendar_time{};
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) {
class ScopeInit final {
public:
ScopeInit() {
- CoreTiming::Init();
+ Core::Timing::Init();
}
~ScopeInit() {
- CoreTiming::Shutdown();
+ Core::Timing::Shutdown();
}
};
@@ -44,37 +44,37 @@ static void AdvanceAndCheck(u32 idx, int downcount, int expected_lateness = 0,
expected_callback = CB_IDS[idx];
lateness = expected_lateness;
- CoreTiming::AddTicks(CoreTiming::GetDowncount() -
- cpu_downcount); // Pretend we executed X cycles of instructions.
- CoreTiming::Advance();
+ // Pretend we executed X cycles of instructions.
+ Core::Timing::AddTicks(Core::Timing::GetDowncount() - cpu_downcount);
+ Core::Timing::Advance();
REQUIRE(decltype(callbacks_ran_flags)().set(idx) == callbacks_ran_flags);
- REQUIRE(downcount == CoreTiming::GetDowncount());
+ REQUIRE(downcount == Core::Timing::GetDowncount());
}
TEST_CASE("CoreTiming[BasicOrder]", "[core]") {
ScopeInit guard;
- CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>);
- CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>);
- CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", CallbackTemplate<2>);
- CoreTiming::EventType* cb_d = CoreTiming::RegisterEvent("callbackD", CallbackTemplate<3>);
- CoreTiming::EventType* cb_e = CoreTiming::RegisterEvent("callbackE", CallbackTemplate<4>);
+ Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>);
+ Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>);
+ Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", CallbackTemplate<2>);
+ Core::Timing::EventType* cb_d = Core::Timing::RegisterEvent("callbackD", CallbackTemplate<3>);
+ Core::Timing::EventType* cb_e = Core::Timing::RegisterEvent("callbackE", CallbackTemplate<4>);
// Enter slice 0
- CoreTiming::Advance();
+ Core::Timing::Advance();
// D -> B -> C -> A -> E
- CoreTiming::ScheduleEvent(1000, cb_a, CB_IDS[0]);
- REQUIRE(1000 == CoreTiming::GetDowncount());
- CoreTiming::ScheduleEvent(500, cb_b, CB_IDS[1]);
- REQUIRE(500 == CoreTiming::GetDowncount());
- CoreTiming::ScheduleEvent(800, cb_c, CB_IDS[2]);
- REQUIRE(500 == CoreTiming::GetDowncount());
- CoreTiming::ScheduleEvent(100, cb_d, CB_IDS[3]);
- REQUIRE(100 == CoreTiming::GetDowncount());
- CoreTiming::ScheduleEvent(1200, cb_e, CB_IDS[4]);
- REQUIRE(100 == CoreTiming::GetDowncount());
+ Core::Timing::ScheduleEvent(1000, cb_a, CB_IDS[0]);
+ REQUIRE(1000 == Core::Timing::GetDowncount());
+ Core::Timing::ScheduleEvent(500, cb_b, CB_IDS[1]);
+ REQUIRE(500 == Core::Timing::GetDowncount());
+ Core::Timing::ScheduleEvent(800, cb_c, CB_IDS[2]);
+ REQUIRE(500 == Core::Timing::GetDowncount());
+ Core::Timing::ScheduleEvent(100, cb_d, CB_IDS[3]);
+ REQUIRE(100 == Core::Timing::GetDowncount());
+ Core::Timing::ScheduleEvent(1200, cb_e, CB_IDS[4]);
+ REQUIRE(100 == Core::Timing::GetDowncount());
AdvanceAndCheck(3, 400);
AdvanceAndCheck(1, 300);
@@ -86,36 +86,36 @@ TEST_CASE("CoreTiming[BasicOrder]", "[core]") {
TEST_CASE("CoreTiming[Threadsave]", "[core]") {
ScopeInit guard;
- CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>);
- CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>);
- CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", CallbackTemplate<2>);
- CoreTiming::EventType* cb_d = CoreTiming::RegisterEvent("callbackD", CallbackTemplate<3>);
- CoreTiming::EventType* cb_e = CoreTiming::RegisterEvent("callbackE", CallbackTemplate<4>);
+ Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>);
+ Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>);
+ Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", CallbackTemplate<2>);
+ Core::Timing::EventType* cb_d = Core::Timing::RegisterEvent("callbackD", CallbackTemplate<3>);
+ Core::Timing::EventType* cb_e = Core::Timing::RegisterEvent("callbackE", CallbackTemplate<4>);
// Enter slice 0
- CoreTiming::Advance();
+ Core::Timing::Advance();
// D -> B -> C -> A -> E
- CoreTiming::ScheduleEventThreadsafe(1000, cb_a, CB_IDS[0]);
+ Core::Timing::ScheduleEventThreadsafe(1000, cb_a, CB_IDS[0]);
// Manually force since ScheduleEventThreadsafe doesn't call it
- CoreTiming::ForceExceptionCheck(1000);
- REQUIRE(1000 == CoreTiming::GetDowncount());
- CoreTiming::ScheduleEventThreadsafe(500, cb_b, CB_IDS[1]);
+ Core::Timing::ForceExceptionCheck(1000);
+ REQUIRE(1000 == Core::Timing::GetDowncount());
+ Core::Timing::ScheduleEventThreadsafe(500, cb_b, CB_IDS[1]);
// Manually force since ScheduleEventThreadsafe doesn't call it
- CoreTiming::ForceExceptionCheck(500);
- REQUIRE(500 == CoreTiming::GetDowncount());
- CoreTiming::ScheduleEventThreadsafe(800, cb_c, CB_IDS[2]);
+ Core::Timing::ForceExceptionCheck(500);
+ REQUIRE(500 == Core::Timing::GetDowncount());
+ Core::Timing::ScheduleEventThreadsafe(800, cb_c, CB_IDS[2]);
// Manually force since ScheduleEventThreadsafe doesn't call it
- CoreTiming::ForceExceptionCheck(800);
- REQUIRE(500 == CoreTiming::GetDowncount());
- CoreTiming::ScheduleEventThreadsafe(100, cb_d, CB_IDS[3]);
+ Core::Timing::ForceExceptionCheck(800);
+ REQUIRE(500 == Core::Timing::GetDowncount());
+ Core::Timing::ScheduleEventThreadsafe(100, cb_d, CB_IDS[3]);
// Manually force since ScheduleEventThreadsafe doesn't call it
- CoreTiming::ForceExceptionCheck(100);
- REQUIRE(100 == CoreTiming::GetDowncount());
- CoreTiming::ScheduleEventThreadsafe(1200, cb_e, CB_IDS[4]);
+ Core::Timing::ForceExceptionCheck(100);
+ REQUIRE(100 == Core::Timing::GetDowncount());
+ Core::Timing::ScheduleEventThreadsafe(1200, cb_e, CB_IDS[4]);
// Manually force since ScheduleEventThreadsafe doesn't call it
- CoreTiming::ForceExceptionCheck(1200);
- REQUIRE(100 == CoreTiming::GetDowncount());
+ Core::Timing::ForceExceptionCheck(1200);
+ REQUIRE(100 == Core::Timing::GetDowncount());
AdvanceAndCheck(3, 400);
AdvanceAndCheck(1, 300);
@@ -143,42 +143,42 @@ TEST_CASE("CoreTiming[SharedSlot]", "[core]") {
ScopeInit guard;
- CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", FifoCallback<0>);
- CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", FifoCallback<1>);
- CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", FifoCallback<2>);
- CoreTiming::EventType* cb_d = CoreTiming::RegisterEvent("callbackD", FifoCallback<3>);
- CoreTiming::EventType* cb_e = CoreTiming::RegisterEvent("callbackE", FifoCallback<4>);
+ Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", FifoCallback<0>);
+ Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", FifoCallback<1>);
+ Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", FifoCallback<2>);
+ Core::Timing::EventType* cb_d = Core::Timing::RegisterEvent("callbackD", FifoCallback<3>);
+ Core::Timing::EventType* cb_e = Core::Timing::RegisterEvent("callbackE", FifoCallback<4>);
- CoreTiming::ScheduleEvent(1000, cb_a, CB_IDS[0]);
- CoreTiming::ScheduleEvent(1000, cb_b, CB_IDS[1]);
- CoreTiming::ScheduleEvent(1000, cb_c, CB_IDS[2]);
- CoreTiming::ScheduleEvent(1000, cb_d, CB_IDS[3]);
- CoreTiming::ScheduleEvent(1000, cb_e, CB_IDS[4]);
+ Core::Timing::ScheduleEvent(1000, cb_a, CB_IDS[0]);
+ Core::Timing::ScheduleEvent(1000, cb_b, CB_IDS[1]);
+ Core::Timing::ScheduleEvent(1000, cb_c, CB_IDS[2]);
+ Core::Timing::ScheduleEvent(1000, cb_d, CB_IDS[3]);
+ Core::Timing::ScheduleEvent(1000, cb_e, CB_IDS[4]);
// Enter slice 0
- CoreTiming::Advance();
- REQUIRE(1000 == CoreTiming::GetDowncount());
+ Core::Timing::Advance();
+ REQUIRE(1000 == Core::Timing::GetDowncount());
callbacks_ran_flags = 0;
counter = 0;
lateness = 0;
- CoreTiming::AddTicks(CoreTiming::GetDowncount());
- CoreTiming::Advance();
- REQUIRE(MAX_SLICE_LENGTH == CoreTiming::GetDowncount());
+ Core::Timing::AddTicks(Core::Timing::GetDowncount());
+ Core::Timing::Advance();
+ REQUIRE(MAX_SLICE_LENGTH == Core::Timing::GetDowncount());
REQUIRE(0x1FULL == callbacks_ran_flags.to_ullong());
}
-TEST_CASE("CoreTiming[PredictableLateness]", "[core]") {
+TEST_CASE("Core::Timing[PredictableLateness]", "[core]") {
ScopeInit guard;
- CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>);
- CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>);
+ Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>);
+ Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>);
// Enter slice 0
- CoreTiming::Advance();
+ Core::Timing::Advance();
- CoreTiming::ScheduleEvent(100, cb_a, CB_IDS[0]);
- CoreTiming::ScheduleEvent(200, cb_b, CB_IDS[1]);
+ Core::Timing::ScheduleEvent(100, cb_a, CB_IDS[0]);
+ Core::Timing::ScheduleEvent(200, cb_b, CB_IDS[1]);
AdvanceAndCheck(0, 90, 10, -10); // (100 - 10)
AdvanceAndCheck(1, MAX_SLICE_LENGTH, 50, -50);
@@ -192,9 +192,10 @@ static void RescheduleCallback(u64 userdata, s64 cycles_late) {
REQUIRE(reschedules >= 0);
REQUIRE(lateness == cycles_late);
- if (reschedules > 0)
- CoreTiming::ScheduleEvent(1000, reinterpret_cast<CoreTiming::EventType*>(userdata),
- userdata);
+ if (reschedules > 0) {
+ Core::Timing::ScheduleEvent(1000, reinterpret_cast<Core::Timing::EventType*>(userdata),
+ userdata);
+ }
}
} // namespace ChainSchedulingTest
@@ -203,35 +204,35 @@ TEST_CASE("CoreTiming[ChainScheduling]", "[core]") {
ScopeInit guard;
- CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>);
- CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>);
- CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", CallbackTemplate<2>);
- CoreTiming::EventType* cb_rs =
- CoreTiming::RegisterEvent("callbackReschedule", RescheduleCallback);
+ Core::Timing::EventType* cb_a = Core::Timing::RegisterEvent("callbackA", CallbackTemplate<0>);
+ Core::Timing::EventType* cb_b = Core::Timing::RegisterEvent("callbackB", CallbackTemplate<1>);
+ Core::Timing::EventType* cb_c = Core::Timing::RegisterEvent("callbackC", CallbackTemplate<2>);
+ Core::Timing::EventType* cb_rs =
+ Core::Timing::RegisterEvent("callbackReschedule", RescheduleCallback);
// Enter slice 0
- CoreTiming::Advance();
+ Core::Timing::Advance();
- CoreTiming::ScheduleEvent(800, cb_a, CB_IDS[0]);
- CoreTiming::ScheduleEvent(1000, cb_b, CB_IDS[1]);
- CoreTiming::ScheduleEvent(2200, cb_c, CB_IDS[2]);
- CoreTiming::ScheduleEvent(1000, cb_rs, reinterpret_cast<u64>(cb_rs));
- REQUIRE(800 == CoreTiming::GetDowncount());
+ Core::Timing::ScheduleEvent(800, cb_a, CB_IDS[0]);
+ Core::Timing::ScheduleEvent(1000, cb_b, CB_IDS[1]);
+ Core::Timing::ScheduleEvent(2200, cb_c, CB_IDS[2]);
+ Core::Timing::ScheduleEvent(1000, cb_rs, reinterpret_cast<u64>(cb_rs));
+ REQUIRE(800 == Core::Timing::GetDowncount());
reschedules = 3;
AdvanceAndCheck(0, 200); // cb_a
AdvanceAndCheck(1, 1000); // cb_b, cb_rs
REQUIRE(2 == reschedules);
- CoreTiming::AddTicks(CoreTiming::GetDowncount());
- CoreTiming::Advance(); // cb_rs
+ Core::Timing::AddTicks(Core::Timing::GetDowncount());
+ Core::Timing::Advance(); // cb_rs
REQUIRE(1 == reschedules);
- REQUIRE(200 == CoreTiming::GetDowncount());
+ REQUIRE(200 == Core::Timing::GetDowncount());
AdvanceAndCheck(2, 800); // cb_c
- CoreTiming::AddTicks(CoreTiming::GetDowncount());
- CoreTiming::Advance(); // cb_rs
+ Core::Timing::AddTicks(Core::Timing::GetDowncount());
+ Core::Timing::Advance(); // cb_rs
REQUIRE(0 == reschedules);
- REQUIRE(MAX_SLICE_LENGTH == CoreTiming::GetDowncount());
+ REQUIRE(MAX_SLICE_LENGTH == Core::Timing::GetDowncount());
}
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
debug_utils/debug_utils.h
engines/fermi_2d.cpp
engines/fermi_2d.h
+ engines/kepler_compute.cpp
+ engines/kepler_compute.h
engines/kepler_memory.cpp
engines/kepler_memory.h
engines/maxwell_3d.cpp
engines/maxwell_3d.h
- engines/maxwell_compute.cpp
- engines/maxwell_compute.h
engines/maxwell_dma.cpp
engines/maxwell_dma.h
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 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/memory.h"
+#include "video_core/engines/kepler_compute.h"
+#include "video_core/memory_manager.h"
+
+namespace Tegra::Engines {
+
+KeplerCompute::KeplerCompute(MemoryManager& memory_manager) : memory_manager{memory_manager} {}
+
+KeplerCompute::~KeplerCompute() = default;
+
+void KeplerCompute::CallMethod(const GPU::MethodCall& method_call) {
+ ASSERT_MSG(method_call.method < Regs::NUM_REGS,
+ "Invalid KeplerCompute register, increase the size of the Regs structure");
+
+ regs.reg_array[method_call.method] = method_call.argument;
+
+ switch (method_call.method) {
+ case KEPLER_COMPUTE_REG_INDEX(launch):
+ // Abort execution since compute shaders can be used to alter game memory (e.g. CUDA
+ // kernels)
+ UNREACHABLE_MSG("Compute shaders are not implemented");
+ break;
+ default:
+ break;
+ }
+}
+
+} // 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 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "video_core/gpu.h"
+#include "video_core/memory_manager.h"
namespace Tegra::Engines {
-#define MAXWELL_COMPUTE_REG_INDEX(field_name) \
- (offsetof(Tegra::Engines::MaxwellCompute::Regs, field_name) / sizeof(u32))
+#define KEPLER_COMPUTE_REG_INDEX(field_name) \
+ (offsetof(Tegra::Engines::KeplerCompute::Regs, field_name) / sizeof(u32))
-class MaxwellCompute final {
+class KeplerCompute final {
public:
- MaxwellCompute() = default;
- ~MaxwellCompute() = default;
+ explicit KeplerCompute(MemoryManager& memory_manager);
+ ~KeplerCompute();
+
+ static constexpr std::size_t NumConstBuffers = 8;
struct Regs {
static constexpr std::size_t NUM_REGS = 0xCF8;
union {
struct {
- INSERT_PADDING_WORDS(0x281);
+ INSERT_PADDING_WORDS(0xAF);
- union {
- u32 compute_end;
- BitField<0, 1, u32> unknown;
- } compute;
+ u32 launch;
- INSERT_PADDING_WORDS(0xA76);
+ INSERT_PADDING_WORDS(0xC48);
};
std::array<u32, NUM_REGS> reg_array;
};
} regs{};
-
static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32),
- "MaxwellCompute Regs has wrong size");
+ "KeplerCompute Regs has wrong size");
+
+ MemoryManager& memory_manager;
/// Write the value to the register identified by method.
void CallMethod(const GPU::MethodCall& method_call);
};
#define ASSERT_REG_POSITION(field_name, position) \
- static_assert(offsetof(MaxwellCompute::Regs, field_name) == position * 4, \
+ static_assert(offsetof(KeplerCompute::Regs, field_name) == position * 4, \
"Field " #field_name " has invalid position")
-ASSERT_REG_POSITION(compute, 0x281);
+ASSERT_REG_POSITION(launch, 0xAF);
#undef ASSERT_REG_POSITION
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() {
LongQueryResult query_result{};
query_result.value = result;
// TODO(Subv): Generate a real GPU timestamp and write it here instead of CoreTiming
- query_result.timestamp = CoreTiming::GetTicks();
+ query_result.timestamp = Core::Timing::GetTicks();
Memory::WriteBlock(*address, &query_result, sizeof(query_result));
}
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 @@
-// Copyright 2018 yuzu Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "common/logging/log.h"
-#include "core/core.h"
-#include "video_core/engines/maxwell_compute.h"
-
-namespace Tegra::Engines {
-
-void MaxwellCompute::CallMethod(const GPU::MethodCall& method_call) {
- ASSERT_MSG(method_call.method < Regs::NUM_REGS,
- "Invalid MaxwellCompute register, increase the size of the Regs structure");
-
- regs.reg_array[method_call.method] = method_call.argument;
-
- switch (method_call.method) {
- case MAXWELL_COMPUTE_REG_INDEX(compute): {
- LOG_CRITICAL(HW_GPU, "Compute shaders are not implemented");
- UNREACHABLE();
- break;
- }
- default:
- break;
- }
-}
-
-} // 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 {
};
enum class F2iRoundingOp : u64 {
- None = 0,
+ RoundEven = 0,
Floor = 1,
Ceil = 2,
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 @@
#include "core/core_timing.h"
#include "core/memory.h"
#include "video_core/engines/fermi_2d.h"
+#include "video_core/engines/kepler_compute.h"
#include "video_core/engines/kepler_memory.h"
#include "video_core/engines/maxwell_3d.h"
-#include "video_core/engines/maxwell_compute.h"
#include "video_core/engines/maxwell_dma.h"
#include "video_core/gpu.h"
#include "video_core/rasterizer_interface.h"
@@ -32,7 +32,7 @@ GPU::GPU(VideoCore::RasterizerInterface& rasterizer) {
dma_pusher = std::make_unique<Tegra::DmaPusher>(*this);
maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager);
fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer, *memory_manager);
- maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
+ kepler_compute = std::make_unique<Engines::KeplerCompute>(*memory_manager);
maxwell_dma = std::make_unique<Engines::MaxwellDMA>(rasterizer, *memory_manager);
kepler_memory = std::make_unique<Engines::KeplerMemory>(rasterizer, *memory_manager);
}
@@ -246,8 +246,8 @@ void GPU::CallEngineMethod(const MethodCall& method_call) {
case EngineID::MAXWELL_B:
maxwell_3d->CallMethod(method_call);
break;
- case EngineID::MAXWELL_COMPUTE_B:
- maxwell_compute->CallMethod(method_call);
+ case EngineID::KEPLER_COMPUTE_B:
+ kepler_compute->CallMethod(method_call);
break;
case EngineID::MAXWELL_DMA_COPY_A:
maxwell_dma->CallMethod(method_call);
@@ -283,7 +283,7 @@ void GPU::ProcessSemaphoreTriggerMethod() {
block.sequence = regs.semaphore_sequence;
// TODO(Kmather73): Generate a real GPU timestamp and write it here instead of
// CoreTiming
- block.timestamp = CoreTiming::GetTicks();
+ block.timestamp = Core::Timing::GetTicks();
Memory::WriteBlock(*address, &block, sizeof(block));
} else {
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 {
namespace Engines {
class Fermi2D;
class Maxwell3D;
-class MaxwellCompute;
class MaxwellDMA;
+class KeplerCompute;
class KeplerMemory;
} // namespace Engines
enum class EngineID {
FERMI_TWOD_A = 0x902D, // 2D Engine
MAXWELL_B = 0xB197, // 3D Engine
- MAXWELL_COMPUTE_B = 0xB1C0,
+ KEPLER_COMPUTE_B = 0xB1C0,
KEPLER_INLINE_TO_MEMORY_B = 0xA140,
MAXWELL_DMA_COPY_A = 0xB0B5,
};
@@ -209,7 +209,7 @@ private:
/// 2D engine
std::unique_ptr<Engines::Fermi2D> fermi_2d;
/// Compute engine
- std::unique_ptr<Engines::MaxwellCompute> maxwell_compute;
+ std::unique_ptr<Engines::KeplerCompute> kepler_compute;
/// DMA engine
std::unique_ptr<Engines::MaxwellDMA> maxwell_dma;
/// 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:
constexpr std::array<const char*, 4> coord_constructors = {"float", "vec2", "vec3", "vec4"};
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
- const auto count = static_cast<u32>(operation.GetOperandsCount());
ASSERT(meta);
+ const auto count = static_cast<u32>(operation.GetOperandsCount());
+ const bool has_array = meta->sampler.IsArray();
+ const bool has_shadow = meta->sampler.IsShadow();
+
std::string expr = func;
expr += '(';
expr += GetSampler(meta->sampler);
expr += ", ";
- expr += coord_constructors[meta->coords_count - 1];
+ expr += coord_constructors.at(count + (has_array ? 1 : 0) + (has_shadow ? 1 : 0) - 1);
expr += '(';
for (u32 i = 0; i < count; ++i) {
- const bool is_extra = i >= meta->coords_count;
- const bool is_array = i == meta->array_index;
-
- std::string operand = [&]() {
- if (is_extra && is_extra_int) {
- if (const auto immediate = std::get_if<ImmediateNode>(operation[i])) {
- return std::to_string(static_cast<s32>(immediate->GetValue()));
- } else {
- return "ftoi(" + Visit(operation[i]) + ')';
- }
- } else {
- return Visit(operation[i]);
- }
- }();
- if (is_array) {
- ASSERT(!is_extra);
- operand = "float(ftoi(" + operand + "))";
- }
-
- expr += operand;
+ expr += Visit(operation[i]);
- if (i + 1 == meta->coords_count) {
- expr += ')';
- }
- if (i + 1 < count) {
+ const u32 next = i + 1;
+ if (next < count || has_array || has_shadow)
+ expr += ", ";
+ }
+ if (has_array) {
+ expr += "float(ftoi(" + Visit(meta->array) + "))";
+ }
+ if (has_shadow) {
+ if (has_array)
expr += ", ";
+ expr += Visit(meta->depth_compare);
+ }
+ expr += ')';
+
+ for (const Node extra : meta->extras) {
+ expr += ", ";
+ if (is_extra_int) {
+ if (const auto immediate = std::get_if<ImmediateNode>(extra)) {
+ // Inline the string as an immediate integer in GLSL (some extra arguments are
+ // required to be constant)
+ expr += std::to_string(static_cast<s32>(immediate->GetValue()));
+ } else {
+ expr += "ftoi(" + Visit(extra) + ')';
+ }
+ } else {
+ expr += Visit(extra);
}
}
+
expr += ')';
return expr;
}
@@ -1134,7 +1140,7 @@ private:
Type::HalfFloat);
}
- std::string F4Texture(Operation operation) {
+ std::string Texture(Operation operation) {
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
ASSERT(meta);
@@ -1145,7 +1151,7 @@ private:
return expr + GetSwizzle(meta->element);
}
- std::string F4TextureLod(Operation operation) {
+ std::string TextureLod(Operation operation) {
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
ASSERT(meta);
@@ -1156,7 +1162,7 @@ private:
return expr + GetSwizzle(meta->element);
}
- std::string F4TextureGather(Operation operation) {
+ std::string TextureGather(Operation operation) {
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
ASSERT(meta);
@@ -1164,7 +1170,7 @@ private:
GetSwizzle(meta->element);
}
- std::string F4TextureQueryDimensions(Operation operation) {
+ std::string TextureQueryDimensions(Operation operation) {
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
ASSERT(meta);
@@ -1184,7 +1190,7 @@ private:
return "0";
}
- std::string F4TextureQueryLod(Operation operation) {
+ std::string TextureQueryLod(Operation operation) {
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
ASSERT(meta);
@@ -1195,29 +1201,32 @@ private:
return "0";
}
- std::string F4TexelFetch(Operation operation) {
+ std::string TexelFetch(Operation operation) {
constexpr std::array<const char*, 4> constructors = {"int", "ivec2", "ivec3", "ivec4"};
const auto meta = std::get_if<MetaTexture>(&operation.GetMeta());
- const auto count = static_cast<u32>(operation.GetOperandsCount());
ASSERT(meta);
+ UNIMPLEMENTED_IF(meta->sampler.IsArray());
+ UNIMPLEMENTED_IF(!meta->extras.empty());
+
+ const auto count = static_cast<u32>(operation.GetOperandsCount());
std::string expr = "texelFetch(";
expr += GetSampler(meta->sampler);
expr += ", ";
- expr += constructors[meta->coords_count - 1];
+ expr += constructors.at(count - 1);
expr += '(';
for (u32 i = 0; i < count; ++i) {
expr += VisitOperand(operation, i, Type::Int);
- if (i + 1 == meta->coords_count) {
+ const u32 next = i + 1;
+ if (next == count)
expr += ')';
- }
- if (i + 1 < count) {
+ if (next < count)
expr += ", ";
- }
}
expr += ')';
+
return expr + GetSwizzle(meta->element);
}
@@ -1454,12 +1463,12 @@ private:
&GLSLDecompiler::Logical2HNotEqual,
&GLSLDecompiler::Logical2HGreaterEqual,
- &GLSLDecompiler::F4Texture,
- &GLSLDecompiler::F4TextureLod,
- &GLSLDecompiler::F4TextureGather,
- &GLSLDecompiler::F4TextureQueryDimensions,
- &GLSLDecompiler::F4TextureQueryLod,
- &GLSLDecompiler::F4TexelFetch,
+ &GLSLDecompiler::Texture,
+ &GLSLDecompiler::TextureLod,
+ &GLSLDecompiler::TextureGather,
+ &GLSLDecompiler::TextureQueryDimensions,
+ &GLSLDecompiler::TextureQueryLod,
+ &GLSLDecompiler::TexelFetch,
&GLSLDecompiler::Branch,
&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;
void RendererOpenGL::SwapBuffers(
std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) {
- Core::System::GetInstance().GetPerfStats().EndSystemFrame();
+ system.GetPerfStats().EndSystemFrame();
// Maintain the rasterizer's state as a priority
OpenGLState prev_state = OpenGLState::GetCurState();
@@ -137,8 +137,8 @@ void RendererOpenGL::SwapBuffers(
render_window.PollEvents();
- Core::System::GetInstance().FrameLimiter().DoFrameLimiting(CoreTiming::GetGlobalTimeUs());
- Core::System::GetInstance().GetPerfStats().BeginSystemFrame();
+ system.FrameLimiter().DoFrameLimiting(Core::Timing::GetGlobalTimeUs());
+ system.GetPerfStats().BeginSystemFrame();
// Restore the rasterizer state
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) {
const Node value = Operation(OperationCode::IAdd, PRECISE, op_a, op_b);
- SetInternalFlagsFromInteger(bb, value, instr.op_32.generates_cc);
+ SetInternalFlagsFromInteger(bb, value, instr.generates_cc);
SetRegister(bb, instr.gpr0, value);
break;
}
@@ -284,4 +284,4 @@ void ShaderIR::WriteLop3Instruction(NodeBlock& bb, Register dest, Node op_a, Nod
SetRegister(bb, dest, value);
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // 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) {
value = [&]() {
switch (instr.conversion.f2i.rounding) {
- case Tegra::Shader::F2iRoundingOp::None:
- return value;
+ case Tegra::Shader::F2iRoundingOp::RoundEven:
+ return Operation(OperationCode::FRoundEven, PRECISE, value);
case Tegra::Shader::F2iRoundingOp::Floor:
return Operation(OperationCode::FFloor, PRECISE, value);
case Tegra::Shader::F2iRoundingOp::Ceil:
@@ -146,4 +146,4 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
return pc;
}
-} // namespace VideoCommon::Shader \ No newline at end of file
+} // 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) {
case OpCode::Id::TLD4S: {
UNIMPLEMENTED_IF_MSG(instr.tld4s.UsesMiscMode(TextureMiscMode::AOFFI),
"AOFFI is not implemented");
-
if (instr.tld4s.UsesMiscMode(TextureMiscMode::NODEP)) {
LOG_WARNING(HW_GPU, "TLD4S.NODEP implementation is incomplete");
}
@@ -315,9 +314,8 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
const Node op_a = GetRegister(instr.gpr8);
const Node op_b = GetRegister(instr.gpr20);
- std::vector<Node> coords;
-
// TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction.
+ std::vector<Node> coords;
if (depth_compare) {
// Note: TLD4S coordinate encoding works just like TEXS's
const Node op_y = GetRegister(instr.gpr8.Value() + 1);
@@ -328,18 +326,17 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
coords.push_back(op_a);
coords.push_back(op_b);
}
- const auto num_coords = static_cast<u32>(coords.size());
- coords.push_back(Immediate(static_cast<u32>(instr.tld4s.component)));
+ std::vector<Node> extras;
+ extras.push_back(Immediate(static_cast<u32>(instr.tld4s.component)));
const auto& sampler =
GetSampler(instr.sampler, TextureType::Texture2D, false, depth_compare);
Node4 values;
for (u32 element = 0; element < values.size(); ++element) {
- auto params = coords;
- MetaTexture meta{sampler, element, num_coords};
- values[element] =
- Operation(OperationCode::F4TextureGather, std::move(meta), std::move(params));
+ auto coords_copy = coords;
+ MetaTexture meta{sampler, {}, {}, extras, element};
+ values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
}
WriteTexsInstructionFloat(bb, instr, values);
@@ -360,12 +357,13 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
switch (instr.txq.query_type) {
case Tegra::Shader::TextureQueryType::Dimension: {
for (u32 element = 0; element < 4; ++element) {
- if (instr.txq.IsComponentEnabled(element)) {
- MetaTexture meta{sampler, element};
- const Node value = Operation(OperationCode::F4TextureQueryDimensions,
- std::move(meta), GetRegister(instr.gpr8));
- SetTemporal(bb, indexer++, value);
+ if (!instr.txq.IsComponentEnabled(element)) {
+ continue;
}
+ MetaTexture meta{sampler, {}, {}, {}, element};
+ const Node value =
+ Operation(OperationCode::TextureQueryDimensions, meta, GetRegister(instr.gpr8));
+ SetTemporal(bb, indexer++, value);
}
for (u32 i = 0; i < indexer; ++i) {
SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i));
@@ -412,9 +410,8 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
for (u32 element = 0; element < 2; ++element) {
auto params = coords;
- MetaTexture meta_texture{sampler, element, static_cast<u32>(coords.size())};
- const Node value =
- Operation(OperationCode::F4TextureQueryLod, meta_texture, std::move(params));
+ MetaTexture meta{sampler, {}, {}, {}, element};
+ const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
SetTemporal(bb, element, value);
}
for (u32 element = 0; element < 2; ++element) {
@@ -535,15 +532,16 @@ void ShaderIR::WriteTexsInstructionHalfFloat(NodeBlock& bb, Instruction instr,
}
Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
- TextureProcessMode process_mode, bool depth_compare, bool is_array,
- std::size_t array_offset, std::size_t bias_offset,
- std::vector<Node>&& coords) {
- UNIMPLEMENTED_IF_MSG(
- (texture_type == TextureType::Texture3D && (is_array || depth_compare)) ||
- (texture_type == TextureType::TextureCube && is_array && depth_compare),
- "This method is not supported.");
+ TextureProcessMode process_mode, std::vector<Node> coords,
+ Node array, Node depth_compare, u32 bias_offset) {
+ const bool is_array = array;
+ const bool is_shadow = depth_compare;
- const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, depth_compare);
+ UNIMPLEMENTED_IF_MSG((texture_type == TextureType::Texture3D && (is_array || is_shadow)) ||
+ (texture_type == TextureType::TextureCube && is_array && is_shadow),
+ "This method is not supported.");
+
+ const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, is_shadow);
const bool lod_needed = process_mode == TextureProcessMode::LZ ||
process_mode == TextureProcessMode::LL ||
@@ -552,35 +550,30 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
// LOD selection (either via bias or explicit textureLod) not supported in GL for
// sampler2DArrayShadow and samplerCubeArrayShadow.
const bool gl_lod_supported =
- !((texture_type == Tegra::Shader::TextureType::Texture2D && is_array && depth_compare) ||
- (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && depth_compare));
+ !((texture_type == Tegra::Shader::TextureType::Texture2D && is_array && is_shadow) ||
+ (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow));
const OperationCode read_method =
- lod_needed && gl_lod_supported ? OperationCode::F4TextureLod : OperationCode::F4Texture;
+ lod_needed && gl_lod_supported ? OperationCode::TextureLod : OperationCode::Texture;
UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported);
- std::optional<u32> array_offset_value;
- if (is_array)
- array_offset_value = static_cast<u32>(array_offset);
-
- const auto coords_count = static_cast<u32>(coords.size());
-
+ std::vector<Node> extras;
if (process_mode != TextureProcessMode::None && gl_lod_supported) {
if (process_mode == TextureProcessMode::LZ) {
- coords.push_back(Immediate(0.0f));
+ extras.push_back(Immediate(0.0f));
} else {
// If present, lod or bias are always stored in the register indexed by the gpr20
// field with an offset depending on the usage of the other registers
- coords.push_back(GetRegister(instr.gpr20.Value() + bias_offset));
+ extras.push_back(GetRegister(instr.gpr20.Value() + bias_offset));
}
}
Node4 values;
for (u32 element = 0; element < values.size(); ++element) {
- auto params = coords;
- MetaTexture meta{sampler, element, coords_count, array_offset_value};
- values[element] = Operation(read_method, std::move(meta), std::move(params));
+ auto copy_coords = coords;
+ MetaTexture meta{sampler, array, depth_compare, extras, element};
+ values[element] = Operation(read_method, meta, std::move(copy_coords));
}
return values;
@@ -602,28 +595,22 @@ Node4 ShaderIR::GetTexCode(Instruction instr, TextureType texture_type,
for (std::size_t i = 0; i < coord_count; ++i) {
coords.push_back(GetRegister(coord_register + i));
}
- // 1D.DC in opengl the 2nd component is ignored.
+ // 1D.DC in OpenGL the 2nd component is ignored.
if (depth_compare && !is_array && texture_type == TextureType::Texture1D) {
coords.push_back(Immediate(0.0f));
}
- std::size_t array_offset{};
- if (is_array) {
- array_offset = coords.size();
- coords.push_back(GetRegister(array_register));
- }
+
+ const Node array = is_array ? GetRegister(array_register) : nullptr;
+
+ Node dc{};
if (depth_compare) {
- // Depth is always stored in the register signaled by gpr20
- // or in the next register if lod or bias are used
+ // Depth is always stored in the register signaled by gpr20 or in the next register if lod
+ // or bias are used
const u64 depth_register = instr.gpr20.Value() + (lod_bias_enabled ? 1 : 0);
- coords.push_back(GetRegister(depth_register));
- }
- // Fill ignored coordinates
- while (coords.size() < total_coord_count) {
- coords.push_back(Immediate(0));
+ dc = GetRegister(depth_register);
}
- return GetTextureCode(instr, texture_type, process_mode, depth_compare, is_array, array_offset,
- 0, std::move(coords));
+ return GetTextureCode(instr, texture_type, process_mode, coords, array, dc, 0);
}
Node4 ShaderIR::GetTexsCode(Instruction instr, TextureType texture_type,
@@ -641,6 +628,7 @@ Node4 ShaderIR::GetTexsCode(Instruction instr, TextureType texture_type,
(is_array || !(lod_bias_enabled || depth_compare) || (coord_count > 2))
? static_cast<u64>(instr.gpr20.Value())
: coord_register + 1;
+ const u32 bias_offset = coord_count > 2 ? 1 : 0;
std::vector<Node> coords;
for (std::size_t i = 0; i < coord_count; ++i) {
@@ -648,24 +636,17 @@ Node4 ShaderIR::GetTexsCode(Instruction instr, TextureType texture_type,
coords.push_back(GetRegister(last ? last_coord_register : coord_register + i));
}
- std::size_t array_offset{};
- if (is_array) {
- array_offset = coords.size();
- coords.push_back(GetRegister(array_register));
- }
+ const Node array = is_array ? GetRegister(array_register) : nullptr;
+
+ Node dc{};
if (depth_compare) {
- // Depth is always stored in the register signaled by gpr20
- // or in the next register if lod or bias are used
+ // Depth is always stored in the register signaled by gpr20 or in the next register if lod
+ // or bias are used
const u64 depth_register = instr.gpr20.Value() + (lod_bias_enabled ? 1 : 0);
- coords.push_back(GetRegister(depth_register));
- }
- // Fill ignored coordinates
- while (coords.size() < total_coord_count) {
- coords.push_back(Immediate(0));
+ dc = GetRegister(depth_register);
}
- return GetTextureCode(instr, texture_type, process_mode, depth_compare, is_array, array_offset,
- (coord_count > 2 ? 1 : 0), std::move(coords));
+ return GetTextureCode(instr, texture_type, process_mode, coords, array, dc, bias_offset);
}
Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool depth_compare,
@@ -680,24 +661,16 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
const u64 coord_register = array_register + (is_array ? 1 : 0);
std::vector<Node> coords;
-
- for (size_t i = 0; i < coord_count; ++i) {
+ for (size_t i = 0; i < coord_count; ++i)
coords.push_back(GetRegister(coord_register + i));
- }
- std::optional<u32> array_offset;
- if (is_array) {
- array_offset = static_cast<u32>(coords.size());
- coords.push_back(GetRegister(array_register));
- }
const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, depth_compare);
Node4 values;
for (u32 element = 0; element < values.size(); ++element) {
- auto params = coords;
- MetaTexture meta{sampler, element, static_cast<u32>(coords.size()), array_offset};
- values[element] =
- Operation(OperationCode::F4TextureGather, std::move(meta), std::move(params));
+ auto coords_copy = coords;
+ MetaTexture meta{sampler, GetRegister(array_register), {}, {}, element};
+ values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
}
return values;
@@ -705,7 +678,6 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is_array) {
const std::size_t type_coord_count = GetCoordCount(texture_type);
- const std::size_t total_coord_count = type_coord_count + (is_array ? 1 : 0);
const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL;
// 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
: coord_register + 1;
std::vector<Node> coords;
-
for (std::size_t i = 0; i < type_coord_count; ++i) {
const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1);
coords.push_back(GetRegister(last ? last_coord_register : coord_register + i));
}
- std::optional<u32> array_offset;
- if (is_array) {
- array_offset = static_cast<u32>(coords.size());
- coords.push_back(GetRegister(array_register));
- }
- const auto coords_count = static_cast<u32>(coords.size());
- if (lod_enabled) {
- // When lod is used always is in grp20
- coords.push_back(GetRegister(instr.gpr20));
- } else {
- coords.push_back(Immediate(0));
- }
+ const Node array = is_array ? GetRegister(array_register) : nullptr;
+ // When lod is used always is in gpr20
+ const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0);
const auto& sampler = GetSampler(instr.sampler, texture_type, is_array, false);
Node4 values;
for (u32 element = 0; element < values.size(); ++element) {
- auto params = coords;
- MetaTexture meta{sampler, element, coords_count, array_offset};
- values[element] =
- Operation(OperationCode::F4TexelFetch, std::move(meta), std::move(params));
+ auto coords_copy = coords;
+ MetaTexture meta{sampler, array, {}, {lod}, element};
+ values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
}
return values;
}
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 {
Logical2HNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
Logical2HGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
- F4Texture, /// (MetaTexture, float[N] coords, float[M] params) -> float4
- F4TextureLod, /// (MetaTexture, float[N] coords, float[M] params) -> float4
- F4TextureGather, /// (MetaTexture, float[N] coords, float[M] params) -> float4
- F4TextureQueryDimensions, /// (MetaTexture, float a) -> float4
- F4TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4
- F4TexelFetch, /// (MetaTexture, int[N], int) -> float4
+ Texture, /// (MetaTexture, float[N] coords) -> float4
+ TextureLod, /// (MetaTexture, float[N] coords) -> float4
+ TextureGather, /// (MetaTexture, float[N] coords) -> float4
+ TextureQueryDimensions, /// (MetaTexture, float a) -> float4
+ TextureQueryLod, /// (MetaTexture, float[N] coords) -> float4
+ TexelFetch, /// (MetaTexture, int[N], int) -> float4
Branch, /// (uint branch_target) -> void
PushFlowStack, /// (uint branch_target) -> void
@@ -288,9 +288,10 @@ struct MetaHalfArithmetic {
struct MetaTexture {
const Sampler& sampler;
+ Node array{};
+ Node depth_compare{};
+ std::vector<Node> extras;
u32 element{};
- u32 coords_count{};
- std::optional<u32> array_index;
};
constexpr MetaArithmetic PRECISE = {true};
@@ -754,9 +755,8 @@ private:
bool lod_bias_enabled, std::size_t max_coords, std::size_t max_inputs);
Node4 GetTextureCode(Tegra::Shader::Instruction instr, Tegra::Shader::TextureType texture_type,
- Tegra::Shader::TextureProcessMode process_mode, bool depth_compare,
- bool is_array, std::size_t array_offset, std::size_t bias_offset,
- std::vector<Node>&& coords);
+ Tegra::Shader::TextureProcessMode process_mode, std::vector<Node> coords,
+ Node array, Node depth_compare, u32 bias_offset);
Node GetVideoOperand(Node op, bool is_chunk, bool is_signed, Tegra::Shader::VideoType type,
u64 byte_height);