diff --git a/features/Skylighting/Shaders/Features/Skylighting.ini b/features/Skylighting/Shaders/Features/Skylighting.ini index 2c3ac80135..5611859742 100644 --- a/features/Skylighting/Shaders/Features/Skylighting.ini +++ b/features/Skylighting/Shaders/Features/Skylighting.ini @@ -1,5 +1,5 @@ [Info] -Version = 1-2-4 +Version = 1-3-0 [Nexus] nexusmodid = 139352 diff --git a/features/Terrain Blending/Shaders/Features/TerrainBlending.ini b/features/Terrain Blending/Shaders/Features/TerrainBlending.ini index 9ce999b868..e28d64a619 100644 --- a/features/Terrain Blending/Shaders/Features/TerrainBlending.ini +++ b/features/Terrain Blending/Shaders/Features/TerrainBlending.ini @@ -1,5 +1,5 @@ [Info] -Version = 1-0-2 +Version = 1-1-0 [Nexus] nexusmodid = 157076 diff --git a/src/Deferred.cpp b/src/Deferred.cpp index 479c375a62..5d0c2f4af0 100644 --- a/src/Deferred.cpp +++ b/src/Deferred.cpp @@ -211,9 +211,7 @@ void Deferred::ReflectionsPrepasses() globals::game::stateUpdateFlags->set(RE::BSGraphics::ShaderFlags::DIRTY_RENDERTARGET); // Run OMSetRenderTargets again - Feature::ForEachLoadedFeature("ReflectionsPrepass", [](Feature* feature) { - feature->ReflectionsPrepass(); - }); + Feature::ForEachLoadedFeature("ReflectionsPrepass", [](Feature* feature) { feature->ReflectionsPrepass(); }, true); } void Deferred::EarlyPrepasses() @@ -236,9 +234,7 @@ void Deferred::EarlyPrepasses() // Shadow maps have just been rendered — upload BSShadowDirectionalLight data to t98. CopyShadowLightData(); - Feature::ForEachLoadedFeature("EarlyPrepass", [](Feature* feature) { - feature->EarlyPrepass(); - }); + Feature::ForEachLoadedFeature("EarlyPrepass", [](Feature* feature) { feature->EarlyPrepass(); }, true); } void Deferred::PrepassPasses() @@ -255,9 +251,7 @@ void Deferred::PrepassPasses() context->OMSetRenderTargets(0, nullptr, nullptr); // Unbind all bound render targets globals::truePBR->PrePass(); - Feature::ForEachLoadedFeature("Prepass", [](Feature* feature) { - feature->Prepass(); - }); + Feature::ForEachLoadedFeature("Prepass", [](Feature* feature) { feature->Prepass(); }, true); } void Deferred::StartDeferred() diff --git a/src/Feature.h b/src/Feature.h index 3371632266..96433bb64d 100644 --- a/src/Feature.h +++ b/src/Feature.h @@ -5,6 +5,7 @@ #include "FeatureVersions.h" #ifdef TRACY_ENABLE # include +# include #endif struct Feature @@ -213,19 +214,28 @@ struct Feature * @param methodName Name of the method being called (used for Tracy zone naming) * @param callback Callable that receives (Feature*) and performs the operation */ + // Called once from State after TracyD3D11Context is created so ForEachLoadedFeature + // can emit GPU timer zones without pulling in State headers here. +#ifdef TRACY_ENABLE + inline static TracyD3D11Ctx s_tracyCtx = nullptr; + static void SetTracyCtx(TracyD3D11Ctx ctx) noexcept { s_tracyCtx = ctx; } +#endif + template - static inline void ForEachLoadedFeature(std::string_view methodName, Func&& callback) + static inline void ForEachLoadedFeature(std::string_view methodName, Func&& callback, bool emitGpuZone = false) { for (auto* feature : GetFeatureList()) { if (feature->loaded) { #ifdef TRACY_ENABLE { - // ZoneTransientN allocates the source location dynamically so the - // runtime string becomes the zone's actual name in Tracy, not just - // a per-instance annotation on a static "ForEachLoadedFeature" zone. const auto zoneName = std::format("{}::{}", feature->GetShortName(), methodName); ZoneTransientN(___tracy_feature_zone, zoneName.c_str(), true); - callback(feature); + if (emitGpuZone) { + TracyD3D11ZoneTransientS(s_tracyCtx, ___tracy_d3d11_feature_zone, zoneName.c_str(), 0, s_tracyCtx != nullptr); + callback(feature); + } else { + callback(feature); + } } #else callback(feature); diff --git a/src/Features/IBL.cpp b/src/Features/IBL.cpp index 557853a756..7ccd7cad56 100644 --- a/src/Features/IBL.cpp +++ b/src/Features/IBL.cpp @@ -199,14 +199,10 @@ void IBL::ReflectionsPrepass() void IBL::Prepass() { - ZoneScoped; - TracyD3D11Zone(globals::state->tracyCtx, "IBL"); - if (settings.DisableInInteriors && Util::IsInterior()) return; auto context = globals::d3d::context; - auto state = globals::state; auto& dynamicCubemaps = globals::features::dynamicCubemaps; @@ -218,7 +214,6 @@ void IBL::Prepass() context->PSSetShaderResources(76, 2, views); } - state->BeginPerfEvent("IBL"); std::array srvs = { (dynamicCubemaps.loaded && envTexture) ? envTexture->srv.get() : nullptr }; std::array uavs = { envIBLTexture->uav.get() }; std::array samplers = { Deferred::GetSingleton()->linearSampler }; @@ -261,7 +256,6 @@ void IBL::Prepass() context->CSSetUnorderedAccessViews(0, (uint)uavs.size(), uavs.data(), nullptr); context->CSSetShader(nullptr, nullptr, 0); } - state->EndPerfEvent(); // Set PS shader resource { diff --git a/src/Features/ScreenSpaceShadows.cpp b/src/Features/ScreenSpaceShadows.cpp index 6f1a8194d9..3a736133c4 100644 --- a/src/Features/ScreenSpaceShadows.cpp +++ b/src/Features/ScreenSpaceShadows.cpp @@ -124,7 +124,7 @@ ID3D11ComputeShader* ScreenSpaceShadows::GetComputeRaymarchRight() void ScreenSpaceShadows::DrawShadows() { - ZoneScoped; + ZoneScopedS(8); auto state = globals::state; TracyD3D11Zone(state->tracyCtx, "Screen Space Shadows"); diff --git a/src/Features/Skylighting.cpp b/src/Features/Skylighting.cpp index 25d761a06c..4f6d6a22ba 100644 --- a/src/Features/Skylighting.cpp +++ b/src/Features/Skylighting.cpp @@ -474,6 +474,7 @@ void Skylighting::SetViewFrustumVR::thunk(RE::NiCamera* a_camera, RE::NiFrustum* void Skylighting::RenderOcclusion() { + ZoneScopedS(8); auto shaderCache = globals::shaderCache; auto state = globals::state; auto renderer = globals::game::renderer; @@ -574,8 +575,11 @@ void Skylighting::RenderOcclusion() PrecipitationShaderDirection = { PrecipitationShaderDirectionF.x, PrecipitationShaderDirectionF.y, PrecipitationShaderDirectionF.z }; static REL::Relocation)> _computeProjection{ REL::RelocationID(25643, 26185) }; - _computeProjection(precip, precip->occlusionData.camera); - precip->SetupMask(); + { + ZoneScopedN("Skylighting - Setup Projection"); + _computeProjection(precip, precip->occlusionData.camera); + precip->SetupMask(); + } BSParticleShaderRainEmitter* rain = new BSParticleShaderRainEmitter; { @@ -596,7 +600,10 @@ void Skylighting::RenderOcclusion() precipitation = precipitationCopy; - _computeProjection(precip, precip->occlusionData.camera); + { + ZoneScopedN("Skylighting - Restore Projection"); + _computeProjection(precip, precip->occlusionData.camera); + } state->EndPerfEvent(); } diff --git a/src/Features/TerrainBlending.cpp b/src/Features/TerrainBlending.cpp index d096013b59..7248d920f4 100644 --- a/src/Features/TerrainBlending.cpp +++ b/src/Features/TerrainBlending.cpp @@ -831,7 +831,7 @@ void TerrainBlending::ClearShaderCache() void TerrainBlending::Hooks::Main_RenderDepth::thunk(bool a1, bool a2) { - ZoneScoped; + ZoneScopedS(8); auto& singleton = globals::features::terrainBlending; auto shaderCache = globals::shaderCache; @@ -859,7 +859,10 @@ void TerrainBlending::Hooks::Main_RenderDepth::thunk(bool a1, bool a2) singleton.renderDepth = true; singleton.ResetDepth(); - func(a1, a2); + { + ZoneScopedN("Terrain Depth - Game Render"); + func(a1, a2); + } singleton.renderDepth = false; @@ -873,7 +876,10 @@ void TerrainBlending::Hooks::Main_RenderDepth::thunk(bool a1, bool a2) mainDepth.depthSRV = singleton.depthSRVBackup; zPrepassCopy.depthSRV = singleton.prepassSRVBackup; - func(a1, a2); + { + ZoneScopedN("Terrain Depth - Game Render"); + func(a1, a2); + } } } diff --git a/src/State.cpp b/src/State.cpp index 71878b72ed..c0ba1574f4 100644 --- a/src/State.cpp +++ b/src/State.cpp @@ -691,6 +691,9 @@ void State::SetupResources() featureLevel = globals::d3d::device->GetFeatureLevel(); tracyCtx = TracyD3D11Context(globals::d3d::device, globals::d3d::context); +#ifdef TRACY_ENABLE + Feature::SetTracyCtx(tracyCtx); +#endif } void State::ModifyShaderLookup(const RE::BSShader& a_shader, uint& a_vertexDescriptor, uint& a_pixelDescriptor, bool a_forceDeferred)