summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2018-11-15 03:28:36 +0100
committerPierre Bourdon <delroth@gmail.com>2018-11-15 03:32:49 +0100
commitef562ec2f1ed598453bd1b5dbdba4f7fbdad21be (patch)
treee8eb8f6e789f096b7c37f41761a040bef41ad637 /Source/Core
parent97e3200f5799cb43f508fd6c385321bc778c5ffb (diff)
Analytics: add simple framework for game quirks reporting
And use it for reporting games that rely on ICache emulation to some degree. We know of a few but it would be interesting to get a more exhaustive list from crowdsourcing.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Analytics.cpp25
-rw-r--r--Source/Core/Core/Analytics.h16
-rw-r--r--Source/Core/Core/PowerPC/PPCCache.cpp8
3 files changed, 49 insertions, 0 deletions
diff --git a/Source/Core/Core/Analytics.cpp b/Source/Core/Core/Analytics.cpp
index b76f3b09f4..e6f9db25c2 100644
--- a/Source/Core/Core/Analytics.cpp
+++ b/Source/Core/Core/Analytics.cpp
@@ -131,9 +131,34 @@ void DolphinAnalytics::ReportGameStart()
builder.AddData("type", "game-start");
Send(builder);
+ // Reset per-game state.
+ m_reported_quirks.fill(false);
InitializePerformanceSampling();
}
+// Keep in sync with enum class GameQuirk definition.
+const char* GAME_QUIRKS_NAMES[] = {
+ "icache-matters", // ICACHE_MATTERS
+};
+static_assert(sizeof(GAME_QUIRKS_NAMES) / sizeof(GAME_QUIRKS_NAMES[0]) ==
+ static_cast<u32>(GameQuirk::COUNT),
+ "Game quirks names and enum definition are out of sync.");
+
+void DolphinAnalytics::ReportGameQuirk(GameQuirk quirk)
+{
+ u32 quirk_idx = static_cast<u32>(quirk);
+
+ // Only report once per run.
+ if (m_reported_quirks[quirk_idx])
+ return;
+ m_reported_quirks[quirk_idx] = true;
+
+ Common::AnalyticsReportBuilder builder(m_per_game_builder);
+ builder.AddData("type", "quirk");
+ builder.AddData("quirk", GAME_QUIRKS_NAMES[quirk_idx]);
+ Send(builder);
+}
+
void DolphinAnalytics::ReportPerformanceInfo(PerformanceSample&& sample)
{
if (ShouldStartPerformanceSampling())
diff --git a/Source/Core/Core/Analytics.h b/Source/Core/Core/Analytics.h
index c0725efd51..0de0f839f8 100644
--- a/Source/Core/Core/Analytics.h
+++ b/Source/Core/Core/Analytics.h
@@ -4,6 +4,7 @@
#pragma once
+#include <array>
#include <memory>
#include <mutex>
#include <string>
@@ -18,6 +19,14 @@
// Non generic part of the Dolphin Analytics framework. See Common/Analytics.h
// for the main documentation.
+enum class GameQuirk
+{
+ // Sometimes code run from ICache is different from its mirror in RAM.
+ ICACHE_MATTERS = 0,
+
+ COUNT,
+};
+
class DolphinAnalytics
{
public:
@@ -42,6 +51,10 @@ public:
// per-game base data.
void ReportGameStart();
+ // Generates a report for a special condition being hit by a game. This is automatically throttled
+ // to once per game run.
+ void ReportGameQuirk(GameQuirk quirk);
+
struct PerformanceSample
{
double speed_ratio; // See SystemTimers::GetEstimatedEmulationPerformance().
@@ -93,6 +106,9 @@ private:
bool m_sampling_performance_info = false; // Whether we are currently collecting samples.
std::vector<PerformanceSample> m_performance_samples;
+ // What quirks have already been reported about the current game.
+ std::array<bool, static_cast<size_t>(GameQuirk::COUNT)> m_reported_quirks;
+
// Builder that contains all non variable data that should be sent with all
// reports.
Common::AnalyticsReportBuilder m_base_builder;
diff --git a/Source/Core/Core/PowerPC/PPCCache.cpp b/Source/Core/Core/PowerPC/PPCCache.cpp
index 1b8e41b5b1..f3cdefb0c3 100644
--- a/Source/Core/Core/PowerPC/PPCCache.cpp
+++ b/Source/Core/Core/PowerPC/PPCCache.cpp
@@ -8,6 +8,7 @@
#include "Common/ChunkFile.h"
#include "Common/Swap.h"
+#include "Core/Analytics.h"
#include "Core/HW/Memmap.h"
#include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/PowerPC.h"
@@ -148,6 +149,13 @@ u32 InstructionCache::ReadInstruction(u32 addr)
// update plru
plru[set] = (plru[set] & ~s_plru_mask[t]) | s_plru_value[t];
u32 res = Common::swap32(data[set][t][(addr >> 2) & 7]);
+ u32 inmem = Memory::Read_U32(addr);
+ if (res != inmem)
+ {
+ INFO_LOG(POWERPC, "ICache read at %08x returned stale data: CACHED: %08x vs. RAM: %08x", addr,
+ res, inmem);
+ DolphinAnalytics::Instance()->ReportGameQuirk(GameQuirk::ICACHE_MATTERS);
+ }
return res;
}