Multi pass
All checks were successful
CI / React UI Build (push) Successful in 10s
CI / Native Windows Build And Tests (push) Successful in 2m16s
CI / Windows Release Package (push) Successful in 2m28s

This commit is contained in:
2026-05-08 17:28:48 +10:00
parent 596d370f43
commit f85abef237
15 changed files with 197 additions and 66 deletions

View File

@@ -2,7 +2,6 @@
#include <cstring>
#include <string>
#include <utility>
#include <vector>
namespace
@@ -14,6 +13,18 @@ void CopyErrorMessage(const std::string& message, int errorMessageSize, char* er
strncpy_s(errorMessage, errorMessageSize, message.c_str(), _TRUNCATE);
}
std::size_t RequiredTemporaryRenderTargets(const std::vector<OpenGLRenderer::LayerProgram>& layerPrograms)
{
std::size_t requiredTargets = 0;
for (const OpenGLRenderer::LayerProgram& layerProgram : layerPrograms)
{
const std::size_t internalPasses = layerProgram.passes.size() > 0 ? layerProgram.passes.size() - 1 : 0;
if (internalPasses > requiredTargets)
requiredTargets = internalPasses;
}
return requiredTargets;
}
}
OpenGLShaderPrograms::OpenGLShaderPrograms(OpenGLRenderer& renderer, RuntimeHost& runtimeHost) :
@@ -55,6 +66,15 @@ bool OpenGLShaderPrograms::CompileLayerPrograms(unsigned inputFrameWidth, unsign
newPrograms.push_back(layerProgram);
}
std::string targetError;
if (!mRenderer.ReserveTemporaryRenderTargets(RequiredTemporaryRenderTargets(newPrograms), inputFrameWidth, inputFrameHeight, targetError))
{
for (LayerProgram& program : newPrograms)
DestroySingleLayerProgram(program);
CopyErrorMessage(targetError, errorMessageSize, errorMessage);
return false;
}
DestroyLayerPrograms();
mRenderer.ReplaceLayerPrograms(newPrograms);
mCommittedLayerStates = layerStates;
@@ -92,11 +112,7 @@ bool OpenGLShaderPrograms::CommitPreparedLayerPrograms(const PreparedShaderBuild
for (const PreparedLayerShader& preparedLayer : preparedBuild.layers)
{
LayerProgram layerProgram;
std::vector<std::pair<std::string, std::string>> passSources;
passSources.reserve(preparedLayer.passes.size());
for (const PreparedLayerShader::Pass& pass : preparedLayer.passes)
passSources.push_back(std::make_pair(pass.passId, pass.fragmentShaderSource));
if (!mCompiler.CompilePreparedLayerProgram(preparedLayer.state, passSources, layerProgram, errorMessageSize, errorMessage))
if (!mCompiler.CompilePreparedLayerProgram(preparedLayer.state, preparedLayer.passes, layerProgram, errorMessageSize, errorMessage))
{
for (LayerProgram& program : newPrograms)
DestroySingleLayerProgram(program);
@@ -105,6 +121,15 @@ bool OpenGLShaderPrograms::CommitPreparedLayerPrograms(const PreparedShaderBuild
newPrograms.push_back(layerProgram);
}
std::string targetError;
if (!mRenderer.ReserveTemporaryRenderTargets(RequiredTemporaryRenderTargets(newPrograms), inputFrameWidth, inputFrameHeight, targetError))
{
for (LayerProgram& program : newPrograms)
DestroySingleLayerProgram(program);
CopyErrorMessage(targetError, errorMessageSize, errorMessage);
return false;
}
DestroyLayerPrograms();
mRenderer.ReplaceLayerPrograms(newPrograms);
mCommittedLayerStates = preparedBuild.layerStates;

View File

@@ -120,15 +120,11 @@ PreparedShaderBuild ShaderBuildQueue::Build(uint64_t generation, unsigned output
{
PreparedLayerShader layer;
layer.state = state;
std::vector<std::pair<std::string, std::string>> passSources;
if (!mRuntimeHost.BuildLayerPassFragmentShaderSources(state.layerId, passSources, build.message))
if (!mRuntimeHost.BuildLayerPassFragmentShaderSources(state.layerId, layer.passes, build.message))
{
build.succeeded = false;
return build;
}
layer.passes.reserve(passSources.size());
for (auto& passSource : passSources)
layer.passes.push_back({ std::move(passSource.first), std::move(passSource.second) });
build.layers.push_back(std::move(layer));
}

View File

@@ -13,14 +13,8 @@ class RuntimeHost;
struct PreparedLayerShader
{
struct Pass
{
std::string passId;
std::string fragmentShaderSource;
};
RuntimeRenderState state;
std::vector<Pass> passes;
std::vector<ShaderPassBuildSource> passes;
};
struct PreparedShaderBuild

View File

@@ -28,7 +28,7 @@ ShaderProgramCompiler::ShaderProgramCompiler(OpenGLRenderer& renderer, RuntimeHo
bool ShaderProgramCompiler::CompileLayerProgram(const RuntimeRenderState& state, LayerProgram& layerProgram, int errorMessageSize, char* errorMessage)
{
std::vector<std::pair<std::string, std::string>> passSources;
std::vector<ShaderPassBuildSource> passSources;
std::string loadError;
if (!mRuntimeHost.BuildLayerPassFragmentShaderSources(state.layerId, passSources, loadError))
@@ -42,12 +42,16 @@ bool ShaderProgramCompiler::CompileLayerProgram(const RuntimeRenderState& state,
bool ShaderProgramCompiler::CompilePreparedLayerProgram(const RuntimeRenderState& state, const std::string& fragmentShaderSource, LayerProgram& layerProgram, int errorMessageSize, char* errorMessage)
{
std::vector<std::pair<std::string, std::string>> passSources;
passSources.push_back(std::make_pair(std::string("main"), fragmentShaderSource));
std::vector<ShaderPassBuildSource> passSources;
ShaderPassBuildSource passSource;
passSource.passId = "main";
passSource.fragmentShaderSource = fragmentShaderSource;
passSource.outputName = "layerOutput";
passSources.push_back(std::move(passSource));
return CompilePreparedLayerProgram(state, passSources, layerProgram, errorMessageSize, errorMessage);
}
bool ShaderProgramCompiler::CompilePreparedLayerProgram(const RuntimeRenderState& state, const std::vector<std::pair<std::string, std::string>>& passSources, LayerProgram& layerProgram, int errorMessageSize, char* errorMessage)
bool ShaderProgramCompiler::CompilePreparedLayerProgram(const RuntimeRenderState& state, const std::vector<ShaderPassBuildSource>& passSources, LayerProgram& layerProgram, int errorMessageSize, char* errorMessage)
{
GLsizei errorBufferSize = 0;
std::string loadError;
@@ -61,7 +65,7 @@ bool ShaderProgramCompiler::CompilePreparedLayerProgram(const RuntimeRenderState
{
GLint compileResult = GL_FALSE;
GLint linkResult = GL_FALSE;
const char* fragmentSource = passSource.second.c_str();
const char* fragmentSource = passSource.fragmentShaderSource.c_str();
ScopedGlShader newVertexShader(glCreateShader(GL_VERTEX_SHADER));
glShaderSource(newVertexShader.get(), 1, (const GLchar**)&vertexSource, NULL);
@@ -121,7 +125,9 @@ bool ShaderProgramCompiler::CompilePreparedLayerProgram(const RuntimeRenderState
mTextureBindings.CreateTextBindings(state, textBindings);
PassProgram passProgram;
passProgram.passId = passSource.first;
passProgram.passId = passSource.passId;
passProgram.inputNames = passSource.inputNames;
passProgram.outputName = passSource.outputName;
passProgram.shaderTextureBase = mTextureBindings.ResolveShaderTextureBase(state, mRuntimeHost.GetMaxTemporalHistoryFrames());
passProgram.textureBindings.swap(textureBindings);
passProgram.textBindings.swap(textBindings);

View File

@@ -5,7 +5,6 @@
#include "ShaderTextureBindings.h"
#include <string>
#include <utility>
#include <vector>
class ShaderProgramCompiler
@@ -18,7 +17,7 @@ public:
bool CompileLayerProgram(const RuntimeRenderState& state, LayerProgram& layerProgram, int errorMessageSize, char* errorMessage);
bool CompilePreparedLayerProgram(const RuntimeRenderState& state, const std::string& fragmentShaderSource, LayerProgram& layerProgram, int errorMessageSize, char* errorMessage);
bool CompilePreparedLayerProgram(const RuntimeRenderState& state, const std::vector<std::pair<std::string, std::string>>& passSources, LayerProgram& layerProgram, int errorMessageSize, char* errorMessage);
bool CompilePreparedLayerProgram(const RuntimeRenderState& state, const std::vector<ShaderPassBuildSource>& passSources, LayerProgram& layerProgram, int errorMessageSize, char* errorMessage);
bool CompileDecodeShader(int errorMessageSize, char* errorMessage);
bool CompileOutputPackShader(int errorMessageSize, char* errorMessage);