Compare commits
2 Commits
7d8f9a39d1
...
87cb55b80b
| Author | SHA1 | Date | |
|---|---|---|---|
| 87cb55b80b | |||
| f458eb0130 |
@@ -101,6 +101,8 @@ std::vector<RenderPassDescriptor> OpenGLRenderPass::BuildLayerPassDescriptors(
|
|||||||
{
|
{
|
||||||
const RuntimeRenderState& state = layerStates[index];
|
const RuntimeRenderState& state = layerStates[index];
|
||||||
LayerProgram& layerProgram = layerPrograms[index];
|
LayerProgram& layerProgram = layerPrograms[index];
|
||||||
|
if (layerProgram.passes.empty())
|
||||||
|
continue;
|
||||||
const std::size_t remaining = layerStates.size() - index;
|
const std::size_t remaining = layerStates.size() - index;
|
||||||
const bool writeToMain = (remaining % 2) == 1;
|
const bool writeToMain = (remaining % 2) == 1;
|
||||||
|
|
||||||
@@ -115,6 +117,7 @@ std::vector<RenderPassDescriptor> OpenGLRenderPass::BuildLayerPassDescriptors(
|
|||||||
pass.sourceFramebuffer = sourceFramebuffer;
|
pass.sourceFramebuffer = sourceFramebuffer;
|
||||||
pass.destinationFramebuffer = writeToMain ? mRenderer.CompositeFramebuffer() : mRenderer.LayerTempFramebuffer();
|
pass.destinationFramebuffer = writeToMain ? mRenderer.CompositeFramebuffer() : mRenderer.LayerTempFramebuffer();
|
||||||
pass.layerProgram = &layerProgram;
|
pass.layerProgram = &layerProgram;
|
||||||
|
pass.passProgram = &layerProgram.passes.front();
|
||||||
pass.layerState = &state;
|
pass.layerState = &state;
|
||||||
pass.capturePreLayerHistory = state.temporalHistorySource == TemporalHistorySource::PreLayerInput;
|
pass.capturePreLayerHistory = state.temporalHistorySource == TemporalHistorySource::PreLayerInput;
|
||||||
passes.push_back(pass);
|
passes.push_back(pass);
|
||||||
@@ -134,13 +137,13 @@ void OpenGLRenderPass::RenderLayerPass(
|
|||||||
const TextBindingUpdater& updateTextBinding,
|
const TextBindingUpdater& updateTextBinding,
|
||||||
const GlobalParamsUpdater& updateGlobalParams)
|
const GlobalParamsUpdater& updateGlobalParams)
|
||||||
{
|
{
|
||||||
if (pass.layerProgram == nullptr || pass.layerState == nullptr)
|
if (pass.passProgram == nullptr || pass.layerState == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RenderShaderProgram(
|
RenderShaderProgram(
|
||||||
pass.sourceTexture,
|
pass.sourceTexture,
|
||||||
pass.destinationFramebuffer,
|
pass.destinationFramebuffer,
|
||||||
*pass.layerProgram,
|
*pass.passProgram,
|
||||||
*pass.layerState,
|
*pass.layerState,
|
||||||
inputFrameWidth,
|
inputFrameWidth,
|
||||||
inputFrameHeight,
|
inputFrameHeight,
|
||||||
@@ -155,7 +158,7 @@ void OpenGLRenderPass::RenderLayerPass(
|
|||||||
void OpenGLRenderPass::RenderShaderProgram(
|
void OpenGLRenderPass::RenderShaderProgram(
|
||||||
GLuint sourceTexture,
|
GLuint sourceTexture,
|
||||||
GLuint destinationFrameBuffer,
|
GLuint destinationFrameBuffer,
|
||||||
LayerProgram& layerProgram,
|
PassProgram& passProgram,
|
||||||
const RuntimeRenderState& state,
|
const RuntimeRenderState& state,
|
||||||
unsigned inputFrameWidth,
|
unsigned inputFrameWidth,
|
||||||
unsigned inputFrameHeight,
|
unsigned inputFrameHeight,
|
||||||
@@ -163,7 +166,7 @@ void OpenGLRenderPass::RenderShaderProgram(
|
|||||||
const TextBindingUpdater& updateTextBinding,
|
const TextBindingUpdater& updateTextBinding,
|
||||||
const GlobalParamsUpdater& updateGlobalParams)
|
const GlobalParamsUpdater& updateGlobalParams)
|
||||||
{
|
{
|
||||||
for (LayerProgram::TextBinding& textBinding : layerProgram.textBindings)
|
for (LayerProgram::TextBinding& textBinding : passProgram.textBindings)
|
||||||
{
|
{
|
||||||
std::string textError;
|
std::string textError;
|
||||||
if (!updateTextBinding(state, textBinding, textError))
|
if (!updateTextBinding(state, textBinding, textError))
|
||||||
@@ -173,52 +176,16 @@ void OpenGLRenderPass::RenderShaderProgram(
|
|||||||
glBindFramebuffer(GL_FRAMEBUFFER, destinationFrameBuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, destinationFrameBuffer);
|
||||||
glViewport(0, 0, inputFrameWidth, inputFrameHeight);
|
glViewport(0, 0, inputFrameWidth, inputFrameHeight);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glActiveTexture(GL_TEXTURE0 + kDecodedVideoTextureUnit);
|
const std::vector<GLuint> sourceHistoryTextures = mRenderer.TemporalHistory().ResolveSourceHistoryTextures(sourceTexture, state.isTemporal ? historyCap : 0);
|
||||||
glBindTexture(GL_TEXTURE_2D, sourceTexture);
|
const std::vector<GLuint> temporalHistoryTextures = mRenderer.TemporalHistory().ResolveTemporalHistoryTextures(state, sourceTexture, state.isTemporal ? historyCap : 0);
|
||||||
mRenderer.TemporalHistory().BindSamplers(state, sourceTexture, historyCap);
|
const ShaderTextureBindings::RuntimeTextureBindingPlan texturePlan =
|
||||||
BindLayerTextureAssets(layerProgram);
|
mTextureBindings.BuildLayerRuntimeBindingPlan(passProgram, sourceTexture, sourceHistoryTextures, temporalHistoryTextures);
|
||||||
|
mTextureBindings.BindRuntimeTexturePlan(texturePlan);
|
||||||
glBindVertexArray(mRenderer.FullscreenVertexArray());
|
glBindVertexArray(mRenderer.FullscreenVertexArray());
|
||||||
glUseProgram(layerProgram.program);
|
glUseProgram(passProgram.program);
|
||||||
updateGlobalParams(state, mRenderer.TemporalHistory().SourceAvailableCount(), mRenderer.TemporalHistory().AvailableCountForLayer(state.layerId));
|
updateGlobalParams(state, mRenderer.TemporalHistory().SourceAvailableCount(), mRenderer.TemporalHistory().AvailableCountForLayer(state.layerId));
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
UnbindLayerTextureAssets(layerProgram, historyCap);
|
mTextureBindings.UnbindRuntimeTexturePlan(texturePlan);
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLRenderPass::BindLayerTextureAssets(const LayerProgram& layerProgram)
|
|
||||||
{
|
|
||||||
const GLuint shaderTextureBase = layerProgram.shaderTextureBase != 0 ? layerProgram.shaderTextureBase : kSourceHistoryTextureUnitBase;
|
|
||||||
for (std::size_t index = 0; index < layerProgram.textureBindings.size(); ++index)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0 + shaderTextureBase + static_cast<GLuint>(index));
|
|
||||||
glBindTexture(GL_TEXTURE_2D, layerProgram.textureBindings[index].texture);
|
|
||||||
}
|
|
||||||
const GLuint textTextureBase = shaderTextureBase + static_cast<GLuint>(layerProgram.textureBindings.size());
|
|
||||||
for (std::size_t index = 0; index < layerProgram.textBindings.size(); ++index)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0 + textTextureBase + static_cast<GLuint>(index));
|
|
||||||
glBindTexture(GL_TEXTURE_2D, layerProgram.textBindings[index].texture);
|
|
||||||
}
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLRenderPass::UnbindLayerTextureAssets(const LayerProgram& layerProgram, unsigned historyCap)
|
|
||||||
{
|
|
||||||
for (unsigned index = 0; index < historyCap; ++index)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0 + kSourceHistoryTextureUnitBase + index);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
glActiveTexture(GL_TEXTURE0 + kSourceHistoryTextureUnitBase + historyCap + index);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
const GLuint shaderTextureBase = layerProgram.shaderTextureBase != 0 ? layerProgram.shaderTextureBase : kSourceHistoryTextureUnitBase;
|
|
||||||
for (std::size_t index = 0; index < layerProgram.textureBindings.size() + layerProgram.textBindings.size(); ++index)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0 + shaderTextureBase + static_cast<GLuint>(index));
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
glActiveTexture(GL_TEXTURE0 + kDecodedVideoTextureUnit);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "OpenGLRenderer.h"
|
#include "OpenGLRenderer.h"
|
||||||
#include "RenderPassDescriptor.h"
|
#include "RenderPassDescriptor.h"
|
||||||
|
#include "ShaderTextureBindings.h"
|
||||||
#include "ShaderTypes.h"
|
#include "ShaderTypes.h"
|
||||||
#include "VideoIOFormat.h"
|
#include "VideoIOFormat.h"
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ class OpenGLRenderPass
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using LayerProgram = OpenGLRenderer::LayerProgram;
|
using LayerProgram = OpenGLRenderer::LayerProgram;
|
||||||
|
using PassProgram = OpenGLRenderer::LayerProgram::PassProgram;
|
||||||
using TextBindingUpdater = std::function<bool(const RuntimeRenderState&, LayerProgram::TextBinding&, std::string&)>;
|
using TextBindingUpdater = std::function<bool(const RuntimeRenderState&, LayerProgram::TextBinding&, std::string&)>;
|
||||||
using GlobalParamsUpdater = std::function<bool(const RuntimeRenderState&, unsigned, unsigned)>;
|
using GlobalParamsUpdater = std::function<bool(const RuntimeRenderState&, unsigned, unsigned)>;
|
||||||
|
|
||||||
@@ -44,15 +46,14 @@ private:
|
|||||||
void RenderShaderProgram(
|
void RenderShaderProgram(
|
||||||
GLuint sourceTexture,
|
GLuint sourceTexture,
|
||||||
GLuint destinationFrameBuffer,
|
GLuint destinationFrameBuffer,
|
||||||
LayerProgram& layerProgram,
|
PassProgram& passProgram,
|
||||||
const RuntimeRenderState& state,
|
const RuntimeRenderState& state,
|
||||||
unsigned inputFrameWidth,
|
unsigned inputFrameWidth,
|
||||||
unsigned inputFrameHeight,
|
unsigned inputFrameHeight,
|
||||||
unsigned historyCap,
|
unsigned historyCap,
|
||||||
const TextBindingUpdater& updateTextBinding,
|
const TextBindingUpdater& updateTextBinding,
|
||||||
const GlobalParamsUpdater& updateGlobalParams);
|
const GlobalParamsUpdater& updateGlobalParams);
|
||||||
void BindLayerTextureAssets(const LayerProgram& layerProgram);
|
|
||||||
void UnbindLayerTextureAssets(const LayerProgram& layerProgram, unsigned historyCap);
|
|
||||||
|
|
||||||
OpenGLRenderer& mRenderer;
|
OpenGLRenderer& mRenderer;
|
||||||
|
ShaderTextureBindings mTextureBindings;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ struct RenderPassDescriptor
|
|||||||
GLuint sourceFramebuffer = 0;
|
GLuint sourceFramebuffer = 0;
|
||||||
GLuint destinationFramebuffer = 0;
|
GLuint destinationFramebuffer = 0;
|
||||||
OpenGLRenderer::LayerProgram* layerProgram = nullptr;
|
OpenGLRenderer::LayerProgram* layerProgram = nullptr;
|
||||||
|
OpenGLRenderer::LayerProgram::PassProgram* passProgram = nullptr;
|
||||||
const RuntimeRenderState* layerState = nullptr;
|
const RuntimeRenderState* layerState = nullptr;
|
||||||
bool capturePreLayerHistory = false;
|
bool capturePreLayerHistory = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -212,6 +212,29 @@ void TemporalHistoryBuffers::BindSamplers(const RuntimeRenderState& state, GLuin
|
|||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<GLuint> TemporalHistoryBuffers::ResolveSourceHistoryTextures(GLuint fallbackTexture, unsigned historyCap) const
|
||||||
|
{
|
||||||
|
std::vector<GLuint> textures;
|
||||||
|
textures.reserve(historyCap);
|
||||||
|
for (unsigned index = 0; index < historyCap; ++index)
|
||||||
|
textures.push_back(ResolveTexture(sourceHistoryRing, fallbackTexture, index));
|
||||||
|
return textures;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<GLuint> TemporalHistoryBuffers::ResolveTemporalHistoryTextures(const RuntimeRenderState& state, GLuint fallbackTexture, unsigned historyCap) const
|
||||||
|
{
|
||||||
|
const Ring* temporalRing = nullptr;
|
||||||
|
auto it = preLayerHistoryByLayerId.find(state.layerId);
|
||||||
|
if (it != preLayerHistoryByLayerId.end())
|
||||||
|
temporalRing = &it->second;
|
||||||
|
|
||||||
|
std::vector<GLuint> textures;
|
||||||
|
textures.reserve(historyCap);
|
||||||
|
for (unsigned index = 0; index < historyCap; ++index)
|
||||||
|
textures.push_back(temporalRing ? ResolveTexture(*temporalRing, fallbackTexture, index) : fallbackTexture);
|
||||||
|
return textures;
|
||||||
|
}
|
||||||
|
|
||||||
GLuint TemporalHistoryBuffers::ResolveTexture(const Ring& ring, GLuint fallbackTexture, std::size_t framesAgo) const
|
GLuint TemporalHistoryBuffers::ResolveTexture(const Ring& ring, GLuint fallbackTexture, std::size_t framesAgo) const
|
||||||
{
|
{
|
||||||
if (ring.filledCount == 0 || ring.slots.empty())
|
if (ring.filledCount == 0 || ring.slots.empty())
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ public:
|
|||||||
void PushSourceFramebuffer(GLuint sourceFramebuffer, unsigned frameWidth, unsigned frameHeight);
|
void PushSourceFramebuffer(GLuint sourceFramebuffer, unsigned frameWidth, unsigned frameHeight);
|
||||||
void PushPreLayerFramebuffer(const std::string& layerId, GLuint sourceFramebuffer, unsigned frameWidth, unsigned frameHeight);
|
void PushPreLayerFramebuffer(const std::string& layerId, GLuint sourceFramebuffer, unsigned frameWidth, unsigned frameHeight);
|
||||||
void BindSamplers(const RuntimeRenderState& state, GLuint currentSourceTexture, unsigned historyCap);
|
void BindSamplers(const RuntimeRenderState& state, GLuint currentSourceTexture, unsigned historyCap);
|
||||||
|
std::vector<GLuint> ResolveSourceHistoryTextures(GLuint fallbackTexture, unsigned historyCap) const;
|
||||||
|
std::vector<GLuint> ResolveTemporalHistoryTextures(const RuntimeRenderState& state, GLuint fallbackTexture, unsigned historyCap) const;
|
||||||
GLuint ResolveTexture(const Ring& ring, GLuint fallbackTexture, std::size_t framesAgo) const;
|
GLuint ResolveTexture(const Ring& ring, GLuint fallbackTexture, std::size_t framesAgo) const;
|
||||||
unsigned SourceAvailableCount() const;
|
unsigned SourceAvailableCount() const;
|
||||||
unsigned AvailableCountForLayer(const std::string& layerId) const;
|
unsigned AvailableCountForLayer(const std::string& layerId) const;
|
||||||
|
|||||||
@@ -155,43 +155,47 @@ void OpenGLRenderer::DestroyResources()
|
|||||||
|
|
||||||
void OpenGLRenderer::DestroySingleLayerProgram(LayerProgram& layerProgram)
|
void OpenGLRenderer::DestroySingleLayerProgram(LayerProgram& layerProgram)
|
||||||
{
|
{
|
||||||
for (LayerProgram::TextureBinding& binding : layerProgram.textureBindings)
|
for (LayerProgram::PassProgram& passProgram : layerProgram.passes)
|
||||||
{
|
{
|
||||||
if (binding.texture != 0)
|
for (LayerProgram::TextureBinding& binding : passProgram.textureBindings)
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &binding.texture);
|
if (binding.texture != 0)
|
||||||
binding.texture = 0;
|
{
|
||||||
|
glDeleteTextures(1, &binding.texture);
|
||||||
|
binding.texture = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
passProgram.textureBindings.clear();
|
||||||
|
|
||||||
|
for (LayerProgram::TextBinding& binding : passProgram.textBindings)
|
||||||
|
{
|
||||||
|
if (binding.texture != 0)
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &binding.texture);
|
||||||
|
binding.texture = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
passProgram.textBindings.clear();
|
||||||
|
|
||||||
|
if (passProgram.program != 0)
|
||||||
|
{
|
||||||
|
glDeleteProgram(passProgram.program);
|
||||||
|
passProgram.program = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (passProgram.fragmentShader != 0)
|
||||||
|
{
|
||||||
|
glDeleteShader(passProgram.fragmentShader);
|
||||||
|
passProgram.fragmentShader = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (passProgram.vertexShader != 0)
|
||||||
|
{
|
||||||
|
glDeleteShader(passProgram.vertexShader);
|
||||||
|
passProgram.vertexShader = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
layerProgram.textureBindings.clear();
|
layerProgram.passes.clear();
|
||||||
|
|
||||||
for (LayerProgram::TextBinding& binding : layerProgram.textBindings)
|
|
||||||
{
|
|
||||||
if (binding.texture != 0)
|
|
||||||
{
|
|
||||||
glDeleteTextures(1, &binding.texture);
|
|
||||||
binding.texture = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
layerProgram.textBindings.clear();
|
|
||||||
|
|
||||||
if (layerProgram.program != 0)
|
|
||||||
{
|
|
||||||
glDeleteProgram(layerProgram.program);
|
|
||||||
layerProgram.program = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layerProgram.fragmentShader != 0)
|
|
||||||
{
|
|
||||||
glDeleteShader(layerProgram.fragmentShader);
|
|
||||||
layerProgram.fragmentShader = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layerProgram.vertexShader != 0)
|
|
||||||
{
|
|
||||||
glDeleteShader(layerProgram.vertexShader);
|
|
||||||
layerProgram.vertexShader = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::DestroyLayerPrograms()
|
void OpenGLRenderer::DestroyLayerPrograms()
|
||||||
|
|||||||
@@ -37,12 +37,19 @@ public:
|
|||||||
|
|
||||||
std::string layerId;
|
std::string layerId;
|
||||||
std::string shaderId;
|
std::string shaderId;
|
||||||
GLuint shaderTextureBase = 0;
|
|
||||||
GLuint program = 0;
|
struct PassProgram
|
||||||
GLuint vertexShader = 0;
|
{
|
||||||
GLuint fragmentShader = 0;
|
std::string passId;
|
||||||
std::vector<TextureBinding> textureBindings;
|
GLuint shaderTextureBase = 0;
|
||||||
std::vector<TextBinding> textBindings;
|
GLuint program = 0;
|
||||||
|
GLuint vertexShader = 0;
|
||||||
|
GLuint fragmentShader = 0;
|
||||||
|
std::vector<TextureBinding> textureBindings;
|
||||||
|
std::vector<TextBinding> textBindings;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<PassProgram> passes;
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint CaptureTexture() const { return mCaptureTexture; }
|
GLuint CaptureTexture() const { return mCaptureTexture; }
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "GlShaderSources.h"
|
#include "GlShaderSources.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -101,51 +102,28 @@ bool ShaderProgramCompiler::CompilePreparedLayerProgram(const RuntimeRenderState
|
|||||||
std::vector<LayerProgram::TextBinding> textBindings;
|
std::vector<LayerProgram::TextBinding> textBindings;
|
||||||
mTextureBindings.CreateTextBindings(state, textBindings);
|
mTextureBindings.CreateTextBindings(state, textBindings);
|
||||||
|
|
||||||
|
layerProgram.layerId = state.layerId;
|
||||||
|
layerProgram.shaderId = state.shaderId;
|
||||||
|
|
||||||
|
PassProgram passProgram;
|
||||||
|
passProgram.passId = "main";
|
||||||
|
passProgram.shaderTextureBase = mTextureBindings.ResolveShaderTextureBase(state, mRuntimeHost.GetMaxTemporalHistoryFrames());
|
||||||
|
passProgram.textureBindings.swap(textureBindings);
|
||||||
|
passProgram.textBindings.swap(textBindings);
|
||||||
|
|
||||||
const GLuint globalParamsIndex = glGetUniformBlockIndex(newProgram.get(), "GlobalParams");
|
const GLuint globalParamsIndex = glGetUniformBlockIndex(newProgram.get(), "GlobalParams");
|
||||||
if (globalParamsIndex != GL_INVALID_INDEX)
|
if (globalParamsIndex != GL_INVALID_INDEX)
|
||||||
glUniformBlockBinding(newProgram.get(), globalParamsIndex, kGlobalParamsBindingPoint);
|
glUniformBlockBinding(newProgram.get(), globalParamsIndex, kGlobalParamsBindingPoint);
|
||||||
|
|
||||||
const unsigned historyCap = mRuntimeHost.GetMaxTemporalHistoryFrames();
|
const unsigned historyCap = mRuntimeHost.GetMaxTemporalHistoryFrames();
|
||||||
const GLuint shaderTextureBase = state.isTemporal ? kSourceHistoryTextureUnitBase + historyCap + historyCap : kSourceHistoryTextureUnitBase;
|
|
||||||
glUseProgram(newProgram.get());
|
glUseProgram(newProgram.get());
|
||||||
const GLint videoInputLocation = glGetUniformLocation(newProgram.get(), "gVideoInput");
|
mTextureBindings.AssignLayerSamplerUniforms(newProgram.get(), state, passProgram, historyCap);
|
||||||
if (videoInputLocation >= 0)
|
|
||||||
glUniform1i(videoInputLocation, static_cast<GLint>(kDecodedVideoTextureUnit));
|
|
||||||
for (unsigned index = 0; index < historyCap; ++index)
|
|
||||||
{
|
|
||||||
const std::string sourceSamplerName = "gSourceHistory" + std::to_string(index);
|
|
||||||
const GLint sourceSamplerLocation = glGetUniformLocation(newProgram.get(), sourceSamplerName.c_str());
|
|
||||||
if (sourceSamplerLocation >= 0)
|
|
||||||
glUniform1i(sourceSamplerLocation, static_cast<GLint>(kSourceHistoryTextureUnitBase + index));
|
|
||||||
|
|
||||||
const std::string temporalSamplerName = "gTemporalHistory" + std::to_string(index);
|
|
||||||
const GLint temporalSamplerLocation = glGetUniformLocation(newProgram.get(), temporalSamplerName.c_str());
|
|
||||||
if (temporalSamplerLocation >= 0)
|
|
||||||
glUniform1i(temporalSamplerLocation, static_cast<GLint>(kSourceHistoryTextureUnitBase + historyCap + index));
|
|
||||||
}
|
|
||||||
for (std::size_t index = 0; index < textureBindings.size(); ++index)
|
|
||||||
{
|
|
||||||
const GLint textureSamplerLocation = mTextureBindings.FindSamplerUniformLocation(newProgram.get(), textureBindings[index].samplerName);
|
|
||||||
if (textureSamplerLocation >= 0)
|
|
||||||
glUniform1i(textureSamplerLocation, static_cast<GLint>(shaderTextureBase + static_cast<GLuint>(index)));
|
|
||||||
}
|
|
||||||
const GLuint textTextureBase = shaderTextureBase + static_cast<GLuint>(textureBindings.size());
|
|
||||||
for (std::size_t index = 0; index < textBindings.size(); ++index)
|
|
||||||
{
|
|
||||||
const GLint textSamplerLocation = mTextureBindings.FindSamplerUniformLocation(newProgram.get(), textBindings[index].samplerName);
|
|
||||||
if (textSamplerLocation >= 0)
|
|
||||||
glUniform1i(textSamplerLocation, static_cast<GLint>(textTextureBase + static_cast<GLuint>(index)));
|
|
||||||
}
|
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
|
||||||
layerProgram.layerId = state.layerId;
|
passProgram.program = newProgram.release();
|
||||||
layerProgram.shaderId = state.shaderId;
|
passProgram.vertexShader = newVertexShader.release();
|
||||||
layerProgram.shaderTextureBase = shaderTextureBase;
|
passProgram.fragmentShader = newFragmentShader.release();
|
||||||
layerProgram.program = newProgram.release();
|
layerProgram.passes.push_back(std::move(passProgram));
|
||||||
layerProgram.vertexShader = newVertexShader.release();
|
|
||||||
layerProgram.fragmentShader = newFragmentShader.release();
|
|
||||||
layerProgram.textureBindings.swap(textureBindings);
|
|
||||||
layerProgram.textBindings.swap(textBindings);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class ShaderProgramCompiler
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using LayerProgram = OpenGLRenderer::LayerProgram;
|
using LayerProgram = OpenGLRenderer::LayerProgram;
|
||||||
|
using PassProgram = OpenGLRenderer::LayerProgram::PassProgram;
|
||||||
|
|
||||||
ShaderProgramCompiler(OpenGLRenderer& renderer, RuntimeHost& runtimeHost, ShaderTextureBindings& textureBindings);
|
ShaderProgramCompiler(OpenGLRenderer& renderer, RuntimeHost& runtimeHost, ShaderTextureBindings& textureBindings);
|
||||||
|
|
||||||
|
|||||||
@@ -102,3 +102,122 @@ GLint ShaderTextureBindings::FindSamplerUniformLocation(GLuint program, const st
|
|||||||
return location;
|
return location;
|
||||||
return glGetUniformLocation(program, (samplerName + "_0").c_str());
|
return glGetUniformLocation(program, (samplerName + "_0").c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint ShaderTextureBindings::ResolveShaderTextureBase(const RuntimeRenderState& state, unsigned historyCap) const
|
||||||
|
{
|
||||||
|
return state.isTemporal ? kSourceHistoryTextureUnitBase + historyCap + historyCap : kSourceHistoryTextureUnitBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderTextureBindings::AssignLayerSamplerUniforms(GLuint program, const RuntimeRenderState& state, const PassProgram& passProgram, unsigned historyCap) const
|
||||||
|
{
|
||||||
|
const GLuint shaderTextureBase = ResolveShaderTextureBase(state, historyCap);
|
||||||
|
|
||||||
|
const GLint videoInputLocation = glGetUniformLocation(program, "gVideoInput");
|
||||||
|
if (videoInputLocation >= 0)
|
||||||
|
glUniform1i(videoInputLocation, static_cast<GLint>(kDecodedVideoTextureUnit));
|
||||||
|
|
||||||
|
for (unsigned index = 0; index < historyCap; ++index)
|
||||||
|
{
|
||||||
|
const std::string sourceSamplerName = "gSourceHistory" + std::to_string(index);
|
||||||
|
const GLint sourceSamplerLocation = glGetUniformLocation(program, sourceSamplerName.c_str());
|
||||||
|
if (sourceSamplerLocation >= 0)
|
||||||
|
glUniform1i(sourceSamplerLocation, static_cast<GLint>(kSourceHistoryTextureUnitBase + index));
|
||||||
|
|
||||||
|
const std::string temporalSamplerName = "gTemporalHistory" + std::to_string(index);
|
||||||
|
const GLint temporalSamplerLocation = glGetUniformLocation(program, temporalSamplerName.c_str());
|
||||||
|
if (temporalSamplerLocation >= 0)
|
||||||
|
glUniform1i(temporalSamplerLocation, static_cast<GLint>(kSourceHistoryTextureUnitBase + historyCap + index));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t index = 0; index < passProgram.textureBindings.size(); ++index)
|
||||||
|
{
|
||||||
|
const GLint textureSamplerLocation = FindSamplerUniformLocation(program, passProgram.textureBindings[index].samplerName);
|
||||||
|
if (textureSamplerLocation >= 0)
|
||||||
|
glUniform1i(textureSamplerLocation, static_cast<GLint>(shaderTextureBase + static_cast<GLuint>(index)));
|
||||||
|
}
|
||||||
|
|
||||||
|
const GLuint textTextureBase = shaderTextureBase + static_cast<GLuint>(passProgram.textureBindings.size());
|
||||||
|
for (std::size_t index = 0; index < passProgram.textBindings.size(); ++index)
|
||||||
|
{
|
||||||
|
const GLint textSamplerLocation = FindSamplerUniformLocation(program, passProgram.textBindings[index].samplerName);
|
||||||
|
if (textSamplerLocation >= 0)
|
||||||
|
glUniform1i(textSamplerLocation, static_cast<GLint>(textTextureBase + static_cast<GLuint>(index)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderTextureBindings::RuntimeTextureBindingPlan ShaderTextureBindings::BuildLayerRuntimeBindingPlan(
|
||||||
|
const PassProgram& passProgram,
|
||||||
|
GLuint layerInputTexture,
|
||||||
|
const std::vector<GLuint>& sourceHistoryTextures,
|
||||||
|
const std::vector<GLuint>& temporalHistoryTextures) const
|
||||||
|
{
|
||||||
|
RuntimeTextureBindingPlan plan;
|
||||||
|
plan.bindings.push_back({ "layerInput", "gVideoInput", layerInputTexture, kDecodedVideoTextureUnit });
|
||||||
|
|
||||||
|
for (std::size_t index = 0; index < sourceHistoryTextures.size(); ++index)
|
||||||
|
{
|
||||||
|
plan.bindings.push_back({
|
||||||
|
"sourceHistory",
|
||||||
|
"gSourceHistory" + std::to_string(index),
|
||||||
|
sourceHistoryTextures[index],
|
||||||
|
kSourceHistoryTextureUnitBase + static_cast<GLuint>(index)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const GLuint temporalBase = kSourceHistoryTextureUnitBase + static_cast<GLuint>(sourceHistoryTextures.size());
|
||||||
|
for (std::size_t index = 0; index < temporalHistoryTextures.size(); ++index)
|
||||||
|
{
|
||||||
|
plan.bindings.push_back({
|
||||||
|
"temporalHistory",
|
||||||
|
"gTemporalHistory" + std::to_string(index),
|
||||||
|
temporalHistoryTextures[index],
|
||||||
|
temporalBase + static_cast<GLuint>(index)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const GLuint shaderTextureBase = passProgram.shaderTextureBase != 0 ? passProgram.shaderTextureBase : kSourceHistoryTextureUnitBase;
|
||||||
|
for (std::size_t index = 0; index < passProgram.textureBindings.size(); ++index)
|
||||||
|
{
|
||||||
|
const LayerProgram::TextureBinding& textureBinding = passProgram.textureBindings[index];
|
||||||
|
plan.bindings.push_back({
|
||||||
|
"shaderTexture",
|
||||||
|
textureBinding.samplerName,
|
||||||
|
textureBinding.texture,
|
||||||
|
shaderTextureBase + static_cast<GLuint>(index)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const GLuint textTextureBase = shaderTextureBase + static_cast<GLuint>(passProgram.textureBindings.size());
|
||||||
|
for (std::size_t index = 0; index < passProgram.textBindings.size(); ++index)
|
||||||
|
{
|
||||||
|
const LayerProgram::TextBinding& textBinding = passProgram.textBindings[index];
|
||||||
|
plan.bindings.push_back({
|
||||||
|
"textTexture",
|
||||||
|
textBinding.samplerName,
|
||||||
|
textBinding.texture,
|
||||||
|
textTextureBase + static_cast<GLuint>(index)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return plan;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderTextureBindings::BindRuntimeTexturePlan(const RuntimeTextureBindingPlan& plan) const
|
||||||
|
{
|
||||||
|
for (const RuntimeTextureBinding& binding : plan.bindings)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + binding.textureUnit);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, binding.texture);
|
||||||
|
}
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderTextureBindings::UnbindRuntimeTexturePlan(const RuntimeTextureBindingPlan& plan) const
|
||||||
|
{
|
||||||
|
for (const RuntimeTextureBinding& binding : plan.bindings)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + binding.textureUnit);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,9 +10,32 @@ class ShaderTextureBindings
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using LayerProgram = OpenGLRenderer::LayerProgram;
|
using LayerProgram = OpenGLRenderer::LayerProgram;
|
||||||
|
using PassProgram = OpenGLRenderer::LayerProgram::PassProgram;
|
||||||
|
|
||||||
|
struct RuntimeTextureBinding
|
||||||
|
{
|
||||||
|
std::string semanticName;
|
||||||
|
std::string samplerName;
|
||||||
|
GLuint texture = 0;
|
||||||
|
GLuint textureUnit = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RuntimeTextureBindingPlan
|
||||||
|
{
|
||||||
|
std::vector<RuntimeTextureBinding> bindings;
|
||||||
|
};
|
||||||
|
|
||||||
bool LoadTextureAsset(const ShaderTextureAsset& textureAsset, GLuint& textureId, std::string& error);
|
bool LoadTextureAsset(const ShaderTextureAsset& textureAsset, GLuint& textureId, std::string& error);
|
||||||
void CreateTextBindings(const RuntimeRenderState& state, std::vector<LayerProgram::TextBinding>& textBindings);
|
void CreateTextBindings(const RuntimeRenderState& state, std::vector<LayerProgram::TextBinding>& textBindings);
|
||||||
bool UpdateTextBindingTexture(const RuntimeRenderState& state, LayerProgram::TextBinding& textBinding, std::string& error);
|
bool UpdateTextBindingTexture(const RuntimeRenderState& state, LayerProgram::TextBinding& textBinding, std::string& error);
|
||||||
GLint FindSamplerUniformLocation(GLuint program, const std::string& samplerName) const;
|
GLint FindSamplerUniformLocation(GLuint program, const std::string& samplerName) const;
|
||||||
|
GLuint ResolveShaderTextureBase(const RuntimeRenderState& state, unsigned historyCap) const;
|
||||||
|
void AssignLayerSamplerUniforms(GLuint program, const RuntimeRenderState& state, const PassProgram& passProgram, unsigned historyCap) const;
|
||||||
|
RuntimeTextureBindingPlan BuildLayerRuntimeBindingPlan(
|
||||||
|
const PassProgram& passProgram,
|
||||||
|
GLuint layerInputTexture,
|
||||||
|
const std::vector<GLuint>& sourceHistoryTextures,
|
||||||
|
const std::vector<GLuint>& temporalHistoryTextures) const;
|
||||||
|
void BindRuntimeTexturePlan(const RuntimeTextureBindingPlan& plan) const;
|
||||||
|
void UnbindRuntimeTexturePlan(const RuntimeTextureBindingPlan& plan) const;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user