Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 46 additions & 15 deletions src/Menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ void Menu::SetupImGuiStyle() const
}

bool IsEnabled = false;
bool ShowPerfOverlay = false;

Menu::~Menu()
{
Expand Down Expand Up @@ -581,6 +582,11 @@ void Menu::DrawGeneralSettings()
if (auto _tt = Util::HoverTooltipWrapper()) {
ImGui::Text("Skips a shader being replaced if it hasn't been compiled yet. Also makes compilation blazingly fast!");
}
ImGui::TableNextColumn();
ImGui::Checkbox("Perf Overlay", &ShowPerfOverlay);
if (auto _tt = Util::HoverTooltipWrapper()) {
ImGui::Text("Shows an overlay with performance statistics.");
}

ImGui::EndTable();
}
Expand Down Expand Up @@ -998,20 +1004,7 @@ void Menu::DrawFooter()
ImGui::SameLine();
ImGui::BulletText(std::format("D3D12 Interop: {}", globals::upscaling->d3d12Interop ? "Active" : "Inactive").c_str());
ImGui::SameLine();
ImGui::BulletText(std::format("GPU: {}", globals::state->adapterDescription.c_str()).c_str());

if (dxgiAdapter3) {
ImGui::SameLine();
DXGI_QUERY_VIDEO_MEMORY_INFO videoMemoryInfo;
dxgiAdapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &videoMemoryInfo);

float currentGpuUsage = videoMemoryInfo.CurrentUsage / (1024.f * 1024.f * 1024.f);
float totalGpuMemory = videoMemoryInfo.Budget / (1024.f * 1024.f * 1024.f);
float percent = currentGpuUsage / totalGpuMemory;

auto progressOverlay = std::format("GPU Usage: {:.02f}GB/{:.02f}GB ({:2.1f}%) ", currentGpuUsage, totalGpuMemory, 100 * percent);
ImGui::ProgressBar(percent, ImVec2(500.f, ImGui::GetTextLineHeight()), progressOverlay.c_str());
}
ImGui::Text(std::format("GPU: {}", globals::state->adapterDescription.c_str()).c_str());
}

void Menu::DrawOverlay()
Expand All @@ -1022,7 +1015,7 @@ void Menu::DrawOverlay()
auto failed = shaderCache->GetFailedTasks();
auto hide = shaderCache->IsHideErrors();

if (!(shaderCache->IsCompiling() || IsEnabled || inTestMode || (failed && !hide))) {
if (!(shaderCache->IsCompiling() || IsEnabled || inTestMode || (failed && !hide) || ShowPerfOverlay)) {
auto& io = ImGui::GetIO();
io.ClearInputKeys();
io.ClearEventsQueue();
Expand Down Expand Up @@ -1088,6 +1081,9 @@ void Menu::DrawOverlay()
ImGui::GetIO().MouseDrawCursor = false;
}

if (ShowPerfOverlay)
DrawPerfOverlay();

if (inTestMode) { // In test mode
float seconds = (float)duration_cast<std::chrono::milliseconds>(high_resolution_clock::now() - lastTestSwitch).count() / 1000;
auto remaining = (float)testInterval - seconds;
Expand All @@ -1114,6 +1110,41 @@ void Menu::DrawOverlay()
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
}

void Menu::DrawPerfOverlay()
{
ImGui::SetNextWindowPos(ImVec2(Util::GetNativeViewportSizeScaled(1.f).x, Util::GetNativeViewportSizeScaled(0.f).y + 20.f), ImGuiCond_Always, ImVec2(1.f, 0.f));
ImGui::SetNextWindowSize(Util::GetNativeViewportSizeScaled(0.2f), ImGuiCond_Appearing);
ImGui::Begin("PerformanceOverlay", NULL, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize);
{
ImGui::Text("Draw Calls:");
//ImGui::Text(std::format("None: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::None])).c_str());
ImGui::Text(std::format("Grass: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::Grass])).c_str());
ImGui::Text(std::format("Sky: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::Sky])).c_str());
ImGui::Text(std::format("Water: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::Water])).c_str());
ImGui::Text(std::format("BloodSplatter: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::BloodSplatter])).c_str());
ImGui::Text(std::format("ImageSpace: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::ImageSpace])).c_str());
ImGui::Text(std::format("Lighting: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::Lighting])).c_str());
ImGui::Text(std::format("Effect: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::Effect])).c_str());
ImGui::Text(std::format("Utility: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::Utility])).c_str());
ImGui::Text(std::format("DistantTree: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::DistantTree])).c_str());
ImGui::Text(std::format("Particle: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::Particle])).c_str());
ImGui::Text(std::format("Total: {}", int(globals::state->smoothDrawCalls[RE::BSShader::Type::Total])).c_str());

if (dxgiAdapter3) {
DXGI_QUERY_VIDEO_MEMORY_INFO videoMemoryInfo;
dxgiAdapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &videoMemoryInfo);

float currentGpuUsage = videoMemoryInfo.CurrentUsage / (1024.f * 1024.f * 1024.f);
float totalGpuMemory = videoMemoryInfo.Budget / (1024.f * 1024.f * 1024.f);
float percent = currentGpuUsage / totalGpuMemory;

auto progressOverlay = std::format("GPU: {:.02f}GB/{:.02f}GB ({:2.1f}%) ", currentGpuUsage, totalGpuMemory, 100 * percent);
ImGui::ProgressBar(percent, ImVec2(200.f, ImGui::GetTextLineHeight()), progressOverlay.c_str());
}
ImGui::End();
}
}

const ImGuiKey Menu::VirtualKeyToImGuiKey(WPARAM vkKey)
{
switch (vkKey) {
Expand Down
1 change: 1 addition & 0 deletions src/Menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Menu
void Init();
void DrawSettings();
void DrawOverlay();
void DrawPerfOverlay();

void ProcessInputEvents(RE::InputEvent* const* a_events);
bool ShouldSwallowInput();
Expand Down
11 changes: 11 additions & 0 deletions src/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,17 @@ void State::Draw()
currentExtraDescriptor = 0;

if (frameChecker.IsNewFrame()) {
for (int i = 0; i < RE::BSShader::Type::Total + 1; ++i)
smoothDrawCalls[i] = smoothDrawCalls[i] * 0.95 + drawCalls[i] * 0.05;
for (auto& c : drawCalls)
c = 0;
ID3D11Buffer* buffers[3] = { permutationCB->CB(), sharedDataCB->CB(), featureDataCB->CB() };
context->PSSetConstantBuffers(4, 3, buffers);
context->CSSetConstantBuffers(5, 2, buffers + 1);
}
drawCalls[RE::BSShader::Type::Total]++;
if (currentShader)
drawCalls[currentShader->shaderType.get()]++;

if (currentShader && updateShader) {
auto type = currentShader->shaderType.get();
Expand Down Expand Up @@ -488,6 +495,10 @@ void State::ModifyRenderTarget(RE::RENDER_TARGETS::RENDER_TARGET a_target, RE::B

void State::SetupResources()
{
for (auto& c : drawCalls)
c = 0;
for (auto& c : smoothDrawCalls)
c = 0;
auto renderer = globals::game::renderer;

permutationCB = new ConstantBuffer(ConstantBufferDesc<PermutationCB>());
Expand Down
2 changes: 2 additions & 0 deletions src/State.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class State
bool upscalerLoaded = false;

float timer = 0;
double smoothDrawCalls[RE::BSShader::Type::Total + 1];
int drawCalls[RE::BSShader::Type::Total + 1];

enum ConfigMode
{
Expand Down