reload has a bounded number of shader compilers
Some checks failed
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Failing after 2m10s
CI / Windows Release Package (push) Has been skipped

This commit is contained in:
2026-05-21 17:33:19 +10:00
parent f9aac85e5f
commit 4096e9c26a
2 changed files with 78 additions and 1 deletions

View File

@@ -8,6 +8,7 @@
#include "../runtime/SupportedShaderCatalog.h"
#include "../telemetry/CadenceTelemetry.h"
#include <deque>
#include <functional>
#include <filesystem>
#include <map>
@@ -48,6 +49,9 @@ private:
void RequestRuntimeStatePersistenceLocked();
std::filesystem::path ResolveRuntimeStatePath() const;
void StartLayerShaderBuild(const std::string& layerId, const std::string& shaderId, bool preserveExistingRenderArtifact = false);
void PumpShaderBuildQueue();
void StartQueuedShaderBuild(const std::string& layerId, const std::string& shaderId);
void CompleteLayerShaderBuild(const std::string& layerId);
void RetireLayerShaderBuild(const std::string& layerId);
void CleanupRetiredShaderBuilds();
void StopAllRuntimeShaderBuilds();
@@ -67,6 +71,12 @@ private:
mutable std::mutex mRuntimeLayerMutex;
RuntimeLayerModel mRuntimeLayerModel;
std::mutex mShaderBuildMutex;
struct QueuedShaderBuild
{
std::string layerId;
std::string shaderId;
};
std::deque<QueuedShaderBuild> mQueuedShaderBuilds;
std::map<std::string, std::unique_ptr<RuntimeShaderBridge>> mShaderBuilds;
std::vector<std::unique_ptr<RuntimeShaderBridge>> mRetiredShaderBuilds;
};

View File

@@ -7,9 +7,15 @@
#include <filesystem>
#include <fstream>
#include <sstream>
#include <algorithm>
namespace RenderCadenceCompositor
{
namespace
{
constexpr std::size_t kMaxConcurrentRuntimeShaderBuilds = 2;
}
bool RuntimeLayerController::LoadSupportedShaderCatalog(const std::string& shaderLibrary, unsigned maxTemporalHistoryFrames)
{
const std::filesystem::path shaderRoot = FindRepoPath(shaderLibrary);
@@ -118,31 +124,91 @@ void RuntimeLayerController::StartLayerShaderBuild(const std::string& layerId, c
mRuntimeLayerModel.MarkBuildStarted(layerId, "Runtime Slang build started for shader '" + shaderId + "'.", error, preserveExistingRenderArtifact);
}
{
std::lock_guard<std::mutex> lock(mShaderBuildMutex);
mQueuedShaderBuilds.push_back(QueuedShaderBuild{ layerId, shaderId });
}
PumpShaderBuildQueue();
}
void RuntimeLayerController::PumpShaderBuildQueue()
{
for (;;)
{
QueuedShaderBuild build;
{
std::lock_guard<std::mutex> lock(mShaderBuildMutex);
if (mShaderBuilds.size() >= kMaxConcurrentRuntimeShaderBuilds || mQueuedShaderBuilds.empty())
return;
build = mQueuedShaderBuilds.front();
mQueuedShaderBuilds.pop_front();
if (mShaderBuilds.find(build.layerId) != mShaderBuilds.end())
continue;
}
StartQueuedShaderBuild(build.layerId, build.shaderId);
}
}
void RuntimeLayerController::StartQueuedShaderBuild(const std::string& layerId, const std::string& shaderId)
{
auto bridge = std::make_unique<RuntimeShaderBridge>();
RuntimeShaderBridge* bridgePtr = bridge.get();
{
std::lock_guard<std::mutex> lock(mShaderBuildMutex);
if (mShaderBuilds.size() >= kMaxConcurrentRuntimeShaderBuilds || mShaderBuilds.find(layerId) != mShaderBuilds.end())
{
mQueuedShaderBuilds.push_front(QueuedShaderBuild{ layerId, shaderId });
return;
}
mShaderBuilds[layerId] = std::move(bridge);
}
bridgePtr->Start(
layerId,
shaderId,
[this](const RuntimeShaderArtifact& artifact) {
[this, layerId](const RuntimeShaderArtifact& artifact) {
if (MarkRuntimeBuildReady(artifact))
PublishRuntimeRenderLayers();
CompleteLayerShaderBuild(layerId);
},
[this, layerId](const std::string& message) {
MarkRuntimeBuildFailedForLayer(layerId, message);
LogError("runtime-shader", "Runtime Slang build failed: " + message);
CompleteLayerShaderBuild(layerId);
});
}
void RuntimeLayerController::CompleteLayerShaderBuild(const std::string& layerId)
{
std::unique_ptr<RuntimeShaderBridge> bridge;
{
std::lock_guard<std::mutex> lock(mShaderBuildMutex);
auto bridgeIt = mShaderBuilds.find(layerId);
if (bridgeIt != mShaderBuilds.end())
{
bridge = std::move(bridgeIt->second);
mShaderBuilds.erase(bridgeIt);
mRetiredShaderBuilds.push_back(std::move(bridge));
}
}
PumpShaderBuildQueue();
}
void RuntimeLayerController::RetireLayerShaderBuild(const std::string& layerId)
{
std::unique_ptr<RuntimeShaderBridge> bridge;
{
std::lock_guard<std::mutex> lock(mShaderBuildMutex);
mQueuedShaderBuilds.erase(
std::remove_if(
mQueuedShaderBuilds.begin(),
mQueuedShaderBuilds.end(),
[&layerId](const QueuedShaderBuild& build) {
return build.layerId == layerId;
}),
mQueuedShaderBuilds.end());
auto bridgeIt = mShaderBuilds.find(layerId);
if (bridgeIt == mShaderBuilds.end())
return;
@@ -180,6 +246,7 @@ void RuntimeLayerController::StopAllRuntimeShaderBuilds()
std::vector<std::unique_ptr<RuntimeShaderBridge>> retiredBuilds;
{
std::lock_guard<std::mutex> lock(mShaderBuildMutex);
mQueuedShaderBuilds.clear();
builds.swap(mShaderBuilds);
retiredBuilds.swap(mRetiredShaderBuilds);
}