Introduce FCAT overlay support

This introduces support to overlay FCAT markers on top of other HUD elements.
For more information about nVidia's FCAT tool see: https://nvidia.com/en-us/geforce/technologies/fcat/technology
This patch includes support for the existing parameter infrastructure and it is fully dynamic.

Squashed commit:

Refactor FCAT to use existing parameter handling infrastructure

With this patch the FCAT overlay should be hooked up into the normal
parameter handling infrastructure. This includes support for
configuration file options, which are also part of this commit.
pull/781/head
PMunkes 2 years ago committed by jackun
parent f81369bd68
commit 6a010d8eab

@ -166,6 +166,17 @@ frame_timing
# background_alpha=0.5
# alpha=
### FCAT overlay
### This enables an FCAT overlay to perform frametime analysis on the final image stream.
### Enable the overlay
# fcat
### Set the width of the FCAT overlay.
### 24 is a performance optimization on AMD GPUs that should not have adverse effects on nVidia GPUs.
### A minimum of 20 pixels is recommended by nVidia.
# fcat_overlay_width=24
### Set the screen edge, this can be useful for special displays that don't update from top edge to bottom. This goes from 0 (left side) to 3 (top edge), counter-clockwise.
# fcat_screen_edge=0
### Color customization
# text_color=FFFFFF
# gpu_color=2E9762

@ -0,0 +1,63 @@
#pragma once
#ifndef MANGOHUD_FCAT_H
#define MANGOHUD_FCAT_H
#include <iostream>
#include <vector>
#include <fstream>
#include <chrono>
#include <thread>
#include <condition_variable>
#include <array>
#include "timing.hpp"
#include "overlay_params.h"
#include "overlay.h"
struct fcatoverlay{
const struct overlay_params* params = nullptr;
const std::array<const ImColor,16> sequence={{{255, 255, 255},{0, 255, 0},{0, 0, 255},{255, 0, 0},{0, 128, 128},{0, 0, 128},{0, 128, 0},{0, 255, 255},{128, 0, 0},{192, 192, 192},{128, 0, 128},{128, 128, 0},{128, 128, 128},{255, 0, 255},{255, 255, 0},{255, 128, 0}}};
void update(const struct overlay_params* params_){
params=params_;
};
ImColor get_next_color (const swapchain_stats& sw_stats){
size_t currentColor = sw_stats.n_frames % 16;// should probably be sequence.size(); but this doesn't matter as all FCAT analysis tools use this exact 16 colour sequence.
ImColor output = sequence[currentColor];
return output;
};
std::array<ImVec2,3> get_overlay_corners()
{
unsigned short screen_edge=params->fcat_screen_edge;
auto window_size = ImVec2(params->fcat_overlay_width,ImGui::GetIO().DisplaySize.y);
auto p_min = ImVec2(0.,0.);
auto p_max = ImVec2(window_size.x,ImGui::GetIO().DisplaySize.y);
//Switch the used screen edge, this enables capture from devices with any screen orientation.
//This goes counter-clockwise from the left edge (0)
switch (screen_edge)
{
default:
case 0:
break;
case 1:
window_size = ImVec2(ImGui::GetIO().DisplaySize.x,window_size.x);
p_min = ImVec2(0,ImGui::GetIO().DisplaySize.y - window_size.y);
p_max = ImVec2(ImGui::GetIO().DisplaySize.x,ImGui::GetIO().DisplaySize.y);
break;
case 2:
window_size = ImVec2(window_size.x,ImGui::GetIO().DisplaySize.y);
p_min = ImVec2(ImGui::GetIO().DisplaySize.x-window_size.x,0);
p_max = ImVec2(ImGui::GetIO().DisplaySize.x,ImGui::GetIO().DisplaySize.y);
break;
case 3:
window_size = ImVec2(ImGui::GetIO().DisplaySize.x,window_size.x);
p_min = ImVec2(0,0);
p_max = ImVec2(ImGui::GetIO().DisplaySize.x,window_size.y);
break;
}
std::array<ImVec2,3> output={{p_min,p_max,window_size}};
return output;
};
};
#endif

@ -14,6 +14,7 @@
#include "gpu.h"
#include "memory.h"
#include "timing.hpp"
#include "fcat.h"
#include "mesa/util/macros.h"
#include "battery.h"
#include "gamepad.h"
@ -38,6 +39,7 @@ float g_overflow = 50.f /* 3333ms * 0.5 / 16.6667 / 2 (to edge and back) */;
string gpuString,wineVersion,wineProcess;
uint32_t deviceID;
bool gui_open = false;
bool fcat_open = false;
struct benchmark_stats benchmark;
struct fps_limit fps_limit_stats {};
ImVec2 real_font_size;
@ -49,6 +51,7 @@ bool gpu_metrics_exists = false;
bool steam_focused = false;
vector<float> frametime_data(200,0.f);
int fan_speed;
fcatoverlay fcatstatus;
void init_spdlog()
{
@ -568,6 +571,22 @@ void render_imgui(swapchain_stats& data, struct overlay_params& params, ImVec2&
if((now - logger->last_log_end()) < 12s && !logger->is_active())
render_benchmark(data, params, window_size, height, now);
}
if(params.enabled[OVERLAY_PARAM_ENABLED_fcat])
{
fcatstatus.update(&params);
auto window_corners = fcatstatus.get_overlay_corners();
auto p_min=window_corners[0];
auto p_max=window_corners[1];
auto window_size= window_corners[2];
ImGui::SetNextWindowPos(p_min, ImGuiCond_Always);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0));
ImGui::SetNextWindowSize(window_size);
ImGui::Begin("FCAT", &fcat_open, ImGuiWindowFlags_NoDecoration| ImGuiWindowFlags_NoBackground);
ImGui::GetWindowDrawList()->AddRectFilled(p_min,p_max,fcatstatus.get_next_color(data),0.0);
ImGui::End();
ImGui::PopStyleVar();
}
}
void init_cpu_stats(overlay_params& params)

@ -402,6 +402,8 @@ parse_gl_size_query(const char *str)
#define parse_gl_bind_framebuffer(s) parse_unsigned(s)
#define parse_gl_dont_flip(s) parse_unsigned(s) != 0
#define parse_round_corners(s) parse_unsigned(s)
#define parse_fcat_overlay_width(s) parse_unsigned(s)
#define parse_fcat_screen_edge(s) parse_unsigned(s)
#define parse_cpu_color(s) parse_color(s)
#define parse_gpu_color(s) parse_color(s)
@ -578,6 +580,7 @@ parse_overlay_config(struct overlay_params *params,
params->enabled[OVERLAY_PARAM_ENABLED_gamepad_battery] = false;
params->enabled[OVERLAY_PARAM_ENABLED_gamepad_battery_icon] = true;
params->enabled[OVERLAY_PARAM_ENABLED_throttling_status] = false;
params->enabled[OVERLAY_PARAM_ENABLED_fcat] = false;
params->fps_sampling_period = 500000000; /* 500ms */
params->width = 0;
params->height = 140;
@ -589,6 +592,8 @@ parse_overlay_config(struct overlay_params *params,
params->offset_y = 0;
params->background_alpha = 0.5;
params->alpha = 1.0;
params->fcat_screen_edge = 0;
params->fcat_overlay_width = 24;
params->time_format = "%T";
params->gpu_color = 0x2e9762;
params->cpu_color = 0x2e97cb;

@ -83,6 +83,7 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_BOOL(hide_fsr_sharpness) \
OVERLAY_PARAM_BOOL(fan) \
OVERLAY_PARAM_BOOL(throttling_status) \
OVERLAY_PARAM_BOOL(fcat) \
OVERLAY_PARAM_CUSTOM(fps_sampling_period) \
OVERLAY_PARAM_CUSTOM(output_folder) \
OVERLAY_PARAM_CUSTOM(output_file) \
@ -152,6 +153,8 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_CUSTOM(autostart_log) \
OVERLAY_PARAM_CUSTOM(round_corners) \
OVERLAY_PARAM_CUSTOM(fsr_steam_sharpness) \
OVERLAY_PARAM_CUSTOM(fcat_screen_edge) \
OVERLAY_PARAM_CUSTOM(fcat_overlay_width) \
enum overlay_param_position {
LAYER_POSITION_TOP_LEFT,
@ -252,6 +255,8 @@ struct overlay_params {
std::unordered_map<std::string,std::string> options;
int permit_upload;
int fsr_steam_sharpness;
unsigned short fcat_screen_edge;
unsigned short fcat_overlay_width;
size_t font_params_hash;
};

Loading…
Cancel
Save