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

View File

@@ -7,9 +7,15 @@
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <algorithm>
namespace RenderCadenceCompositor namespace RenderCadenceCompositor
{ {
namespace
{
constexpr std::size_t kMaxConcurrentRuntimeShaderBuilds = 2;
}
bool RuntimeLayerController::LoadSupportedShaderCatalog(const std::string& shaderLibrary, unsigned maxTemporalHistoryFrames) bool RuntimeLayerController::LoadSupportedShaderCatalog(const std::string& shaderLibrary, unsigned maxTemporalHistoryFrames)
{ {
const std::filesystem::path shaderRoot = FindRepoPath(shaderLibrary); 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); 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>(); auto bridge = std::make_unique<RuntimeShaderBridge>();
RuntimeShaderBridge* bridgePtr = bridge.get(); RuntimeShaderBridge* bridgePtr = bridge.get();
{ {
std::lock_guard<std::mutex> lock(mShaderBuildMutex); 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); mShaderBuilds[layerId] = std::move(bridge);
} }
bridgePtr->Start( bridgePtr->Start(
layerId, layerId,
shaderId, shaderId,
[this](const RuntimeShaderArtifact& artifact) { [this, layerId](const RuntimeShaderArtifact& artifact) {
if (MarkRuntimeBuildReady(artifact)) if (MarkRuntimeBuildReady(artifact))
PublishRuntimeRenderLayers(); PublishRuntimeRenderLayers();
CompleteLayerShaderBuild(layerId);
}, },
[this, layerId](const std::string& message) { [this, layerId](const std::string& message) {
MarkRuntimeBuildFailedForLayer(layerId, message); MarkRuntimeBuildFailedForLayer(layerId, message);
LogError("runtime-shader", "Runtime Slang build failed: " + 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) void RuntimeLayerController::RetireLayerShaderBuild(const std::string& layerId)
{ {
std::unique_ptr<RuntimeShaderBridge> bridge; std::unique_ptr<RuntimeShaderBridge> bridge;
{ {
std::lock_guard<std::mutex> lock(mShaderBuildMutex); 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); auto bridgeIt = mShaderBuilds.find(layerId);
if (bridgeIt == mShaderBuilds.end()) if (bridgeIt == mShaderBuilds.end())
return; return;
@@ -180,6 +246,7 @@ void RuntimeLayerController::StopAllRuntimeShaderBuilds()
std::vector<std::unique_ptr<RuntimeShaderBridge>> retiredBuilds; std::vector<std::unique_ptr<RuntimeShaderBridge>> retiredBuilds;
{ {
std::lock_guard<std::mutex> lock(mShaderBuildMutex); std::lock_guard<std::mutex> lock(mShaderBuildMutex);
mQueuedShaderBuilds.clear();
builds.swap(mShaderBuilds); builds.swap(mShaderBuilds);
retiredBuilds.swap(mRetiredShaderBuilds); retiredBuilds.swap(mRetiredShaderBuilds);
} }