Merge pull request #7572 from delroth/analytics-quirks

Analytics: add simple framework for game quirks reporting
This commit is contained in:
Pierre Bourdon 2018-11-30 05:22:45 +01:00 committed by GitHub
commit d9cacf6f5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 0 deletions

View File

@ -131,9 +131,34 @@ void DolphinAnalytics::ReportGameStart()
builder.AddData("type", "game-start"); builder.AddData("type", "game-start");
Send(builder); Send(builder);
// Reset per-game state.
m_reported_quirks.fill(false);
InitializePerformanceSampling(); 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) void DolphinAnalytics::ReportPerformanceInfo(PerformanceSample&& sample)
{ {
if (ShouldStartPerformanceSampling()) if (ShouldStartPerformanceSampling())

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <array>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <string> #include <string>
@ -18,6 +19,14 @@
// Non generic part of the Dolphin Analytics framework. See Common/Analytics.h // Non generic part of the Dolphin Analytics framework. See Common/Analytics.h
// for the main documentation. // 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 class DolphinAnalytics
{ {
public: public:
@ -42,6 +51,10 @@ public:
// per-game base data. // per-game base data.
void ReportGameStart(); 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 struct PerformanceSample
{ {
double speed_ratio; // See SystemTimers::GetEstimatedEmulationPerformance(). double speed_ratio; // See SystemTimers::GetEstimatedEmulationPerformance().
@ -93,6 +106,9 @@ private:
bool m_sampling_performance_info = false; // Whether we are currently collecting samples. bool m_sampling_performance_info = false; // Whether we are currently collecting samples.
std::vector<PerformanceSample> m_performance_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 // Builder that contains all non variable data that should be sent with all
// reports. // reports.
Common::AnalyticsReportBuilder m_base_builder; Common::AnalyticsReportBuilder m_base_builder;

View File

@ -8,6 +8,7 @@
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
#include "Common/Swap.h" #include "Common/Swap.h"
#include "Core/Analytics.h"
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
#include "Core/PowerPC/JitInterface.h" #include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
@ -148,6 +149,13 @@ u32 InstructionCache::ReadInstruction(u32 addr)
// update plru // update plru
plru[set] = (plru[set] & ~s_plru_mask[t]) | s_plru_value[t]; plru[set] = (plru[set] & ~s_plru_mask[t]) | s_plru_value[t];
u32 res = Common::swap32(data[set][t][(addr >> 2) & 7]); 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; return res;
} }