diff --git a/src/core/core.cpp b/src/core/core.cpp index 5429bcb26..d08f18623 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -168,6 +168,16 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { } void System::Shutdown() { + // Log last frame performance stats + auto perf_results = GetAndResetPerfStats(); + Telemetry().AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed", + perf_results.emulation_speed * 100.0); + Telemetry().AddField(Telemetry::FieldType::Performance, "Shutdown_Framerate", + perf_results.game_fps); + Telemetry().AddField(Telemetry::FieldType::Performance, "Shutdown_Frametime", + perf_results.frametime * 1000.0); + + // Shutdown emulation session GDBStub::Shutdown(); AudioCore::Shutdown(); VideoCore::Shutdown(); diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index ffc019560..fc4d14a59 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -342,9 +342,11 @@ ResultStatus AppLoader_NCCH::Load() { if (result != ResultStatus::Success) return result; - LOG_INFO(Loader, "Program ID: %016" PRIX64, ncch_header.program_id); + std::string program_id{Common::StringFromFormat("%016" PRIX64, ncch_header.program_id)}; - Core::Telemetry().AddField(Telemetry::FieldType::Session, "ProgramId", ncch_header.program_id); + LOG_INFO(Loader, "Program ID: %s", program_id.c_str()); + + Core::Telemetry().AddField(Telemetry::FieldType::Session, "ProgramId", program_id); is_loaded = true; // Set state to loaded diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index 70eff4340..841d6cfa1 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp @@ -4,7 +4,10 @@ #include +#include "common/assert.h" #include "common/scm_rev.h" +#include "common/x64/cpu_detect.h" +#include "core/settings.h" #include "core/telemetry_session.h" #ifdef ENABLE_WEB_SERVICE @@ -13,6 +16,18 @@ namespace Core { +static const char* CpuVendorToStr(Common::CPUVendor vendor) { + switch (vendor) { + case Common::CPUVendor::INTEL: + return "Intel"; + case Common::CPUVendor::AMD: + return "Amd"; + case Common::CPUVendor::OTHER: + return "Other"; + } + UNREACHABLE(); +} + TelemetrySession::TelemetrySession() { #ifdef ENABLE_WEB_SERVICE backend = std::make_unique(); @@ -20,22 +35,63 @@ TelemetrySession::TelemetrySession() { backend = std::make_unique(); #endif // Log one-time session start information - const auto duration{std::chrono::steady_clock::now().time_since_epoch()}; - const auto start_time{std::chrono::duration_cast(duration).count()}; - AddField(Telemetry::FieldType::Session, "StartTime", start_time); + const s64 init_time{std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count()}; + AddField(Telemetry::FieldType::Session, "Init_Time", init_time); - // Log one-time application information + // Log application information const bool is_git_dirty{std::strstr(Common::g_scm_desc, "dirty") != nullptr}; - AddField(Telemetry::FieldType::App, "GitIsDirty", is_git_dirty); - AddField(Telemetry::FieldType::App, "GitBranch", Common::g_scm_branch); - AddField(Telemetry::FieldType::App, "GitRevision", Common::g_scm_rev); + AddField(Telemetry::FieldType::App, "Git_IsDirty", is_git_dirty); + AddField(Telemetry::FieldType::App, "Git_Branch", Common::g_scm_branch); + AddField(Telemetry::FieldType::App, "Git_Revision", Common::g_scm_rev); + + // Log user system information + AddField(Telemetry::FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string); + AddField(Telemetry::FieldType::UserSystem, "CPU_BrandString", + Common::GetCPUCaps().brand_string); + AddField(Telemetry::FieldType::UserSystem, "CPU_Vendor", + CpuVendorToStr(Common::GetCPUCaps().vendor)); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_AES", Common::GetCPUCaps().aes); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_AVX", Common::GetCPUCaps().avx); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_AVX2", Common::GetCPUCaps().avx2); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_BMI1", Common::GetCPUCaps().bmi1); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_BMI2", Common::GetCPUCaps().bmi2); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_FMA", Common::GetCPUCaps().fma); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_FMA4", Common::GetCPUCaps().fma4); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE", Common::GetCPUCaps().sse); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE2", Common::GetCPUCaps().sse2); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE3", Common::GetCPUCaps().sse3); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSSE3", + Common::GetCPUCaps().ssse3); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE41", + Common::GetCPUCaps().sse4_1); + AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE42", + Common::GetCPUCaps().sse4_2); + + // Log user configuration information + AddField(Telemetry::FieldType::UserConfig, "Audio_EnableAudioStretching", + Settings::values.enable_audio_stretching); + AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", Settings::values.use_cpu_jit); + AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor", + Settings::values.resolution_factor); + AddField(Telemetry::FieldType::UserConfig, "Renderer_ToggleFramelimit", + Settings::values.toggle_framelimit); + AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwRenderer", + Settings::values.use_hw_renderer); + AddField(Telemetry::FieldType::UserConfig, "Renderer_UseShaderJit", + Settings::values.use_shader_jit); + AddField(Telemetry::FieldType::UserConfig, "Renderer_UseVsync", Settings::values.use_vsync); + AddField(Telemetry::FieldType::UserConfig, "System_IsNew3ds", Settings::values.is_new_3ds); + AddField(Telemetry::FieldType::UserConfig, "System_RegionValue", Settings::values.region_value); } TelemetrySession::~TelemetrySession() { // Log one-time session end information - const auto duration{std::chrono::steady_clock::now().time_since_epoch()}; - const auto end_time{std::chrono::duration_cast(duration).count()}; - AddField(Telemetry::FieldType::Session, "EndTime", end_time); + const s64 shutdown_time{std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count()}; + AddField(Telemetry::FieldType::Session, "Shutdown_Time", shutdown_time); // Complete the session, submitting to web service if necessary // This is just a placeholder to wrap up the session once the core completes and this is diff --git a/src/video_core/renderer_opengl/pica_to_gl.h b/src/video_core/renderer_opengl/pica_to_gl.h index 70298e211..c7fa1f873 100644 --- a/src/video_core/renderer_opengl/pica_to_gl.h +++ b/src/video_core/renderer_opengl/pica_to_gl.h @@ -12,6 +12,7 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/logging/log.h" +#include "core/core.h" #include "video_core/regs_framebuffer.h" #include "video_core/regs_lighting.h" #include "video_core/regs_texturing.h" @@ -72,9 +73,9 @@ inline GLenum WrapMode(Pica::TexturingRegs::TextureConfig::WrapMode mode) { } if (static_cast(mode) > 3) { - // It is still unclear whether mode 4-7 are valid, so log it if a game uses them. - // TODO(wwylele): telemetry should be added here so we can collect more info about which - // game uses this. + Core::Telemetry().AddField(Telemetry::FieldType::Session, + "VideoCore_Pica_UnsupportedTextureWrapMode", + static_cast(mode)); LOG_WARNING(Render_OpenGL, "Using texture wrap mode %u", static_cast(mode)); } diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index d90c776f9..65c18aecc 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -481,9 +481,18 @@ bool RendererOpenGL::Init() { glDebugMessageCallback(DebugHandler, nullptr); } - LOG_INFO(Render_OpenGL, "GL_VERSION: %s", glGetString(GL_VERSION)); - LOG_INFO(Render_OpenGL, "GL_VENDOR: %s", glGetString(GL_VENDOR)); - LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", glGetString(GL_RENDERER)); + const char* gl_version{reinterpret_cast(glGetString(GL_VERSION))}; + const char* gpu_vendor{reinterpret_cast(glGetString(GL_VENDOR))}; + const char* gpu_model{reinterpret_cast(glGetString(GL_RENDERER))}; + + LOG_INFO(Render_OpenGL, "GL_VERSION: %s", gl_version); + LOG_INFO(Render_OpenGL, "GL_VENDOR: %s", gpu_vendor); + LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", gpu_model); + + Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Vendor", gpu_vendor); + Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Model", gpu_model); + Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_OpenGL_Version", gl_version); + if (!GLAD_GL_VERSION_3_3) { return false; }