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
28 changes: 11 additions & 17 deletions src/Deferred.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,18 +238,16 @@ void Deferred::ReflectionsPrepasses()
state->UpdateSharedData(false, false);

ZoneScoped;
TracyD3D11Zone(globals::game::graphicsState->tracyCtx, "Early Prepass");
TracyD3D11Zone(globals::state->tracyCtx, "Reflections Prepass");

auto context = globals::d3d::context;
context->OMSetRenderTargets(0, nullptr, nullptr); // Unbind all bound render targets

globals::game::stateUpdateFlags->set(RE::BSGraphics::ShaderFlags::DIRTY_RENDERTARGET); // Run OMSetRenderTargets again

for (auto* feature : Feature::GetFeatureList()) {
if (feature->loaded) {
feature->ReflectionsPrepass();
}
}
Feature::ForEachLoadedFeature("ReflectionsPrepass", [](Feature* feature) {
feature->ReflectionsPrepass();
});
}

void Deferred::EarlyPrepasses()
Expand All @@ -262,18 +260,16 @@ void Deferred::EarlyPrepasses()
globals::state->UpdateSharedData(false, true);

ZoneScoped;
TracyD3D11Zone(globals::game::graphicsState->tracyCtx, "Early Prepass");
TracyD3D11Zone(globals::state->tracyCtx, "Early Prepass");

auto context = globals::d3d::context;
context->OMSetRenderTargets(0, nullptr, nullptr); // Unbind all bound render targets

globals::game::stateUpdateFlags->set(RE::BSGraphics::ShaderFlags::DIRTY_RENDERTARGET); // Run OMSetRenderTargets again

for (auto* feature : Feature::GetFeatureList()) {
if (feature->loaded) {
feature->EarlyPrepass();
}
}
Feature::ForEachLoadedFeature("EarlyPrepass", [](Feature* feature) {
feature->EarlyPrepass();
});
}

void Deferred::PrepassPasses()
Expand All @@ -290,11 +286,9 @@ void Deferred::PrepassPasses()
context->OMSetRenderTargets(0, nullptr, nullptr); // Unbind all bound render targets

globals::truePBR->PrePass();
for (auto* feature : Feature::GetFeatureList()) {
if (feature->loaded) {
feature->Prepass();
}
}
Feature::ForEachLoadedFeature("Prepass", [](Feature* feature) {
feature->Prepass();
});
}

void Deferred::StartDeferred()
Expand Down
37 changes: 37 additions & 0 deletions src/Feature.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#pragma once

#include "FeatureVersions.h"
#ifdef TRACY_ENABLE
# include <Tracy/Tracy.hpp>
#endif

struct Feature
{
Expand Down Expand Up @@ -165,4 +168,38 @@ struct Feature
* @return True if the feature is found, false otherwise.
*/
static bool IsFeatureKnown(const std::string& shortName, REL::Version* outVersion = nullptr);

/**
* @brief Execute a callable for each loaded feature with optional Tracy CPU profiling
*
* Iterates through all loaded features and calls the provided function with automatic
* CPU profiling zones (ZoneScoped/ZoneText via Tracy) when TRACY_ENABLE is defined.
* Thread-local string formatting is used to minimize per-call overhead.
*
* Usage:
* Feature::ForEachLoadedFeature("Reset", [](Feature* feature) { feature->Reset(); });
* Feature::ForEachLoadedFeature("Prepass", [](Feature* feature) { feature->Prepass(); });
*
* @param methodName Name of the method being called (used for Tracy zone naming)
* @param callback Callable that receives (Feature*) and performs the operation
*/
template <typename Func>
static inline void ForEachLoadedFeature(std::string_view methodName, Func&& callback)
{
for (auto* feature : GetFeatureList()) {
if (feature->loaded) {
#ifdef TRACY_ENABLE
{
ZoneScoped;
static thread_local std::string zoneName;
zoneName = std::format("{}::{}", feature->GetShortName(), methodName);
ZoneText(zoneName.c_str(), zoneName.size());
callback(feature);
}
#else
callback(feature);
#endif
}
}
}
};
8 changes: 2 additions & 6 deletions src/Features/ScreenSpaceShadows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,8 @@ void ScreenSpaceShadows::DrawShadows()
// Shared dispatch logic for both VR and non-VR
auto DispatchEye = [&](const char* eyeName, ID3D11ComputeShader* shader, const float* lightProj,
float invTexSizeX, float invTexSizeY) {
std::string eventName;
const char* tracyName = "SSS - Ray March";

if (globals::state->frameAnnotations && eyeName) {
eventName = std::format("SSS - Ray March ({})", eyeName);
tracyName = eventName.c_str();
std::string eventName = std::format("SSS - Ray March ({})", eyeName);
globals::state->BeginPerfEvent(eventName);
} else if (globals::state->frameAnnotations) {
globals::state->BeginPerfEvent("SSS - Ray March");
Expand All @@ -173,7 +169,7 @@ void ScreenSpaceShadows::DrawShadows()
auto dispatchList = Bend::BuildDispatchList(const_cast<float*>(lightProj), viewportSize, minRenderBounds, maxRenderBounds);

for (int i = 0; i < dispatchList.DispatchCount; i++) {
TracyD3D11Zone(globals::state->tracyCtx, tracyName);
TracyD3D11Zone(globals::state->tracyCtx, "SSS - Ray March");

auto dispatchData = dispatchList.Dispatch[i];

Expand Down
3 changes: 3 additions & 0 deletions src/ShaderCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2645,6 +2645,9 @@ namespace SIE

void ShaderCompilationTask::Perform() const
{
ZoneScoped;
ZoneText(GetString().c_str(), GetString().size());

if (shaderClass == ShaderClass::Vertex) {
ShaderCache::Instance().MakeAndAddVertexShader(shader, descriptor);
} else if (shaderClass == ShaderClass::Pixel) {
Expand Down
31 changes: 20 additions & 11 deletions src/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

void State::Draw()
{
ZoneScoped;

auto shaderCache = globals::shaderCache;
auto deferred = globals::deferred;
auto& terrainBlending = globals::features::terrainBlending;
Expand All @@ -31,19 +33,30 @@ void State::Draw()
auto context = globals::d3d::context;

if (shaderCache->IsEnabled()) {
if (weatherEditor.loaded)
if (weatherEditor.loaded) {
ZoneScopedN("WeatherManager::UpdateFeatures");
WeatherManager::GetSingleton()->UpdateFeatures();
}

if (terrainBlending.loaded && terrainBlending.settings.Enabled)
if (terrainBlending.loaded && terrainBlending.settings.Enabled) {
ZoneScopedN("TerrainBlending::TerrainShaderHacks");
terrainBlending.TerrainShaderHacks();
}

if (cloudShadows.loaded)
if (cloudShadows.loaded) {
ZoneScopedN("CloudShadows::SkyShaderHacks");
cloudShadows.SkyShaderHacks();
}

if (terrainHelper.loaded)
if (terrainHelper.loaded) {
ZoneScopedN("TerrainHelper::SetShaderResouces");
terrainHelper.SetShaderResouces(context);
}

truePBR->SetShaderResouces(context);
{
ZoneScopedN("TruePBR::SetShaderResouces");
truePBR->SetShaderResouces(context);
}

if (permutationData != permutationDataPrevious) {
permutationCB->Update(permutationData);
Expand Down Expand Up @@ -122,9 +135,7 @@ void State::Debug()

void State::Reset()
{
for (auto* feature : Feature::GetFeatureList())
if (feature->loaded)
feature->Reset();
Feature::ForEachLoadedFeature("Reset", [](Feature* feature) { feature->Reset(); });
if (!globals::game::ui->GameIsPaused())
timer += RE::GetSecondsSinceLastFrame();
lastModifiedPixelDescriptor = 0;
Expand Down Expand Up @@ -155,9 +166,7 @@ void State::Setup()
{
globals::truePBR->SetupResources();
SetupResources();
for (auto* feature : Feature::GetFeatureList())
if (feature->loaded)
feature->SetupResources();
Feature::ForEachLoadedFeature("SetupResources", [](Feature* feature) { feature->SetupResources(); });
globals::deferred->SetupResources();

// Load per-weather settings after features are setup
Expand Down
18 changes: 3 additions & 15 deletions src/XSEPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,7 @@ void MessageHandler(SKSE::MessagingInterface::Message* message)
auto shaderCache = globals::shaderCache;

// Run feature PostPostLoad() first so features can disable themselves if needed
for (auto* feature : Feature::GetFeatureList()) {
if (feature->loaded) {
feature->PostPostLoad();
}
}
Feature::ForEachLoadedFeature("PostPostLoad", [](Feature* feature) { feature->PostPostLoad(); });

// Now validate disk cache after features have had a chance to modify their state
shaderCache->ValidateDiskCache();
Expand Down Expand Up @@ -126,11 +122,7 @@ void MessageHandler(SKSE::MessagingInterface::Message* message)
}

globals::truePBR->DataLoaded();
for (auto* feature : Feature::GetFeatureList()) {
if (feature->loaded) {
feature->DataLoaded();
}
}
Feature::ForEachLoadedFeature("DataLoaded", [](Feature* feature) { feature->DataLoaded(); });
}

break;
Expand Down Expand Up @@ -206,11 +198,7 @@ bool Load()
if (errors.empty()) {
Hooks::InstallEarlyHooks();
logger::info("Calling feature Load methods");
for (auto* feature : Feature::GetFeatureList()) {
if (feature->loaded) {
feature->Load();
}
}
Feature::ForEachLoadedFeature("Load", [](Feature* feature) { feature->Load(); });
}

return true;
Expand Down