Permalink
Browse files

Merge pull request #7572 from delroth/analytics-quirks

Analytics: add simple framework for game quirks reporting
  • Loading branch information...
delroth committed Nov 30, 2018
2 parents 4d14d5e + ef562ec commit d9cacf6f5a5c1b5b97e6b29f665ee15fdf38fc50
Showing with 49 additions and 0 deletions.
  1. +25 −0 Source/Core/Core/Analytics.cpp
  2. +16 −0 Source/Core/Core/Analytics.h
  3. +8 −0 Source/Core/Core/PowerPC/PPCCache.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())
@@ -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 @@ class DolphinAnalytics
// 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 @@ class DolphinAnalytics
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;
@@ -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;
}

0 comments on commit d9cacf6

Please sign in to comment.