mangoapp: gamescope debug graphs

gamescope-debug
FlightlessMango 2 years ago
parent cdcd08be44
commit e6b4df7ffa

@ -35,6 +35,8 @@ std::condition_variable mangoapp_cv;
static uint8_t raw_msg[1024] = {0};
uint8_t g_fsrUpscale = 0;
uint8_t g_fsrSharpness = 0;
std::vector<float> gamescope_debug_latency {};
std::vector<float> gamescope_debug_app {};
void ctrl_thread(){
while (1){
@ -74,7 +76,25 @@ void ctrl_thread(){
bool new_frame = false;
void gamescope_frametime(uint64_t app_frametime_ns, uint64_t latency_ns){
float app_frametime_ms = app_frametime_ns / 1000000.f;
gamescope_debug_app.push_back(app_frametime_ms);
if (gamescope_debug_app.size() > 200)
gamescope_debug_app.erase(gamescope_debug_app.begin());
float latency_ms = latency_ns / 1000000.f;
if (latency_ns == -1)
latency_ms = -1;
gamescope_debug_latency.push_back(latency_ms);
if (gamescope_debug_latency.size() > 200)
gamescope_debug_latency.erase(gamescope_debug_latency.begin());
}
void msg_read_thread(){
for (size_t i = 0; i < 200; i++){
gamescope_debug_app.push_back(0);
gamescope_debug_latency.push_back(0);
}
int key = ftok("mangoapp", 65);
msgid = msgget(key, 0666 | IPC_CREAT);
const struct mangoapp_msg_header *hdr = (const struct mangoapp_msg_header*) raw_msg;
@ -84,12 +104,15 @@ void msg_read_thread(){
// and that we're not trying to use variables that don't exist (yet)
size_t msg_size = msgrcv(msgid, (void *) raw_msg, sizeof(raw_msg), 1, 0);
if (hdr->version == 1){
if (msg_size > offsetof(struct mangoapp_msg_v1, frametime_ns)){
update_hud_info_with_frametime(sw_stats, *params, vendorID, mangoapp_v1->frametime_ns);
if (msg_size > offsetof(struct mangoapp_msg_v1, visible_frametime_ns)){
update_hud_info_with_frametime(sw_stats, *params, vendorID, mangoapp_v1->visible_frametime_ns);
if (msg_size > offsetof(mangoapp_msg_v1, fsrUpscale)){
g_fsrUpscale = mangoapp_v1->fsrUpscale;
g_fsrSharpness = mangoapp_v1->fsrSharpness;
}
if (msg_size > offsetof(mangoapp_msg_v1, latency_ns)){
gamescope_frametime(mangoapp_v1->app_frametime_ns, mangoapp_v1->latency_ns);
}
{
std::unique_lock<std::mutex> lk(mangoapp_m);
new_frame = true;

@ -3,6 +3,7 @@
#include <sys/msg.h>
#include <mutex>
#include <condition_variable>
#include <vector>
extern int ctrl_msgid;
extern int msgid;
@ -18,9 +19,12 @@ struct mangoapp_msg_v1 {
struct mangoapp_msg_header hdr;
uint32_t pid;
uint64_t frametime_ns;
uint64_t visible_frametime_ns;
uint8_t fsrUpscale;
uint8_t fsrSharpness;
// For debugging
uint64_t app_frametime_ns;
uint64_t latency_ns;
// WARNING: Always ADD fields, never remove or repurpose fields
} __attribute__((packed));
@ -42,4 +46,6 @@ struct mangoapp_ctrl_msgid1_v1 {
} __attribute__((packed));
extern uint8_t g_fsrUpscale;
extern uint8_t g_fsrSharpness;
extern uint8_t g_fsrSharpness;
extern std::vector<float> gamescope_debug_latency;
extern std::vector<float> gamescope_debug_app;

@ -587,7 +587,11 @@ void HudElements::frame_timing(){
ImGui::PlotLines(hash, get_time_stat, HUDElements.sw_stats,
ARRAY_SIZE(HUDElements.sw_stats->frames_stats), 0,
NULL, min_time, max_time,
ImVec2(ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns, 50));
ImVec2(ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns - 30, 50));
ImGui::SameLine();
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("%.1fms", frametime / 1000.f);
ImGui::PopFont();
}
ImGui::PopStyleColor();
@ -778,6 +782,68 @@ void HudElements::gamescope_fsr(){
#endif
}
void HudElements::gamescope_frame_timing(){
#ifdef MANGOAPP
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_debug]) {
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.colors.engine, "%s", "App");
for (size_t i = 0; i < HUDElements.params->table_columns - 1; i++)
ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
auto min = std::min_element(gamescope_debug_app.begin(), gamescope_debug_app.end());
auto max = std::max_element(gamescope_debug_app.begin(), gamescope_debug_app.end());
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width * 1.3, "min: %.1fms, max: %.1fms", min[0], max[0]);
ImGui::PopFont();
ImGui::TableNextRow(); ImGui::TableNextColumn();
char hash[40];
snprintf(hash, sizeof(hash), "##%s", overlay_param_names[OVERLAY_PARAM_ENABLED_frame_timing]);
HUDElements.sw_stats->stat_selector = OVERLAY_PLOTS_frame_timing;
HUDElements.sw_stats->time_dividor = 1000000.0f; /* ns -> ms */
double min_time = 0.0f;
double max_time = 50.0f;
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
ImGui::PlotLines("", gamescope_debug_app.data(),
gamescope_debug_app.size(), 0,
NULL, min_time, max_time,
ImVec2(ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns - 30, 50));
ImGui::SameLine();
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("%.1fms", gamescope_debug_app.back());
ImGui::PopFont();
ImGui::PopStyleColor();
if (gamescope_debug_latency.back() > -1){
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.colors.engine, "%s", "Latency");
for (size_t i = 0; i < HUDElements.params->table_columns - 1; i++)
ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
min = std::min_element(gamescope_debug_latency.begin(), gamescope_debug_latency.end());
max = std::max_element(gamescope_debug_latency.begin(), gamescope_debug_latency.end());
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width * 1.3, "min: %.1fms, max: %.1fms", min[0], max[0]);
ImGui::PopFont();
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
ImGui::PushStyleColor(ImGuiCol_PlotLines, ImVec4(0,0,1,1));
ImGui::PlotLines("", gamescope_debug_latency.data(),
gamescope_debug_latency.size(), 0,
NULL, min_time, max_time,
ImVec2(ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns - 30, 50));
ImGui::SameLine();
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Text("%.1fms", gamescope_debug_latency.back());
ImGui::PopFont();
ImGui::PopStyleColor(2);
}
}
#endif
}
void HudElements::graphs(){
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
@ -928,6 +994,7 @@ void HudElements::sort_elements(const std::pair<std::string, std::string>& optio
if (param == "battery") { ordered_functions.push_back({battery, value}); }
if (param == "fps_only") { ordered_functions.push_back({fps_only, value}); }
if (param == "fsr") { ordered_functions.push_back({gamescope_fsr, value}); }
if (param == "debug") { ordered_functions.push_back({gamescope_frame_timing, value}); }
if (param == "graphs"){
if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_graphs])
HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_graphs] = true;
@ -971,6 +1038,7 @@ void HudElements::legacy_elements(){
ordered_functions.push_back({wine, value});
#endif
ordered_functions.push_back({frame_timing, value});
ordered_functions.push_back({gamescope_frame_timing, value});
#ifndef MANGOAPP
ordered_functions.push_back({gamemode, value});
ordered_functions.push_back({vkbasalt, value});

@ -60,6 +60,7 @@ class HudElements{
static void battery();
static void fps_only();
static void gamescope_fsr();
static void gamescope_frame_timing();
void convert_colors(struct overlay_params& params);
void convert_colors(bool do_conv, struct overlay_params& params);

@ -76,6 +76,7 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_BOOL(force_amdgpu_hwmon) \
OVERLAY_PARAM_BOOL(fps_only) \
OVERLAY_PARAM_BOOL(fsr) \
OVERLAY_PARAM_BOOL(debug) \
OVERLAY_PARAM_CUSTOM(fps_sampling_period) \
OVERLAY_PARAM_CUSTOM(output_folder) \
OVERLAY_PARAM_CUSTOM(output_file) \

Loading…
Cancel
Save