Skip to content

Commit

Permalink
Clean up multipass rendering logic
Browse files Browse the repository at this point in the history
  • Loading branch information
KOPRajs authored and garbear committed May 10, 2024
1 parent 7df3e2b commit 3a176c2
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 97 deletions.
92 changes: 32 additions & 60 deletions xbmc/cores/RetroPlayer/shaders/gl/ShaderPresetGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ ShaderParameterMap CShaderPresetGL::GetShaderParameters(
return matchParams;
}

bool CShaderPresetGL::RenderUpdate(const CPoint* dest,
bool CShaderPresetGL::RenderUpdate(const CPoint dest[],
IShaderTexture* source,
IShaderTexture* target)
{
Expand All @@ -97,64 +97,46 @@ bool CShaderPresetGL::RenderUpdate(const CPoint* dest,

PrepareParameters(target, dest);

IShader* firstShader = m_pShaders.front().get();
IShader* lastShader = m_pShaders.back().get();

const unsigned passesNum = static_cast<unsigned int>(m_pShaders.size());

if (passesNum == 1)
firstShader->Render(source, target);
else if (passesNum == 2)
// Apply all passes except the last one (which needs to be applied to the backbuffer)
for (unsigned int shaderIdx = 0; shaderIdx < static_cast<unsigned int>(m_pShaders.size()) - 1;
++shaderIdx)
{
// Apply first pass
CShaderTextureGL* firstShaderTexture = m_pShaderTextures.front().get();
firstShaderTexture->BindFBO();
RenderShader(firstShader, source, firstShaderTexture);
firstShaderTexture->UnbindFBO();

// Apply last pass
CRect newViewPort(0.f, 0.f, target->GetWidth(), target->GetHeight());
m_context.SetViewPort(newViewPort);
m_context.SetScissors(newViewPort);
lastShader->Render(firstShaderTexture, target);
IShader* shader = m_pShaders[shaderIdx].get();
IShaderTexture* texture = m_pShaderTextures[shaderIdx].get();
RenderShader(shader, source, texture); // The target is used for setting the viewport and binding the FBO
source = texture;
}
else
{
// Apply first pass
CShaderTextureGL* firstShaderTexture = m_pShaderTextures.front().get();
firstShaderTexture->BindFBO();
RenderShader(firstShader, source, firstShaderTexture);
firstShaderTexture->UnbindFBO();

// Apply all passes except the first and last one (which needs to be applied to the backbuffer)
for (unsigned int shaderIdx = 1; shaderIdx < static_cast<unsigned int>(m_pShaders.size()) - 1;
++shaderIdx)
{
IShader* shader = m_pShaders[shaderIdx].get();
CShaderTextureGL* prevTexture = m_pShaderTextures[shaderIdx - 1].get();
CShaderTextureGL* texture = m_pShaderTextures[shaderIdx].get();
texture->BindFBO();
RenderShader(shader, prevTexture,
texture); // The target on each call is only used for setting the viewport
texture->UnbindFBO();
}

// Apply last pass
CShaderTextureGL* secToLastTexture = m_pShaderTextures[m_pShaderTextures.size() - 2].get();
CRect newViewPort(0.f, 0.f, target->GetWidth(), target->GetHeight());
m_context.SetViewPort(newViewPort);
m_context.SetScissors(newViewPort);
lastShader->Render(secToLastTexture, target);
}
// Restore our viewport
m_context.SetViewPort(viewPort);
m_context.SetScissors(viewPort);

m_frameCount += static_cast<float>(m_speed);
// Apply the last pass and write to target (backbuffer) instead of the last texture
IShader* lastShader = m_pShaders.back().get();
lastShader->Render(source, target);

// Restore our view port.
m_context.SetViewPort(viewPort);
m_frameCount += static_cast<float>(m_speed);

return true;
}

void CShaderPresetGL::RenderShader(IShader* shader,
IShaderTexture* source,
IShaderTexture* target) const
{
if (static_cast<CShaderTextureGL*>(target)->BindFBO())
{
CRect newViewPort(0.f, 0.f, target->GetWidth(), target->GetHeight());
glViewport((GLsizei) newViewPort.x1, (GLsizei) newViewPort.y1,
(GLsizei) newViewPort.x2, (GLsizei) newViewPort.y2);
glScissor((GLsizei) newViewPort.x1, (GLsizei) newViewPort.y1,
(GLsizei) newViewPort.x2, (GLsizei) newViewPort.y2);

shader->Render(source, target);
static_cast<CShaderTextureGL*>(target)->UnbindFBO();
}
}

bool CShaderPresetGL::Update()
{
auto updateFailed = [this](const std::string& msg)
Expand Down Expand Up @@ -461,16 +443,6 @@ void CShaderPresetGL::PrepareParameters(const IShaderTexture* texture, const CPo
m_pShaders.back()->PrepareParameters(m_dest, true, static_cast<uint64_t>(m_frameCount));
}

void CShaderPresetGL::RenderShader(IShader* shader,
IShaderTexture* source,
IShaderTexture* target) const
{
glViewport(0, 0, (GLsizei) target->GetWidth(), (GLsizei) target->GetHeight());
glScissor(0, 0, (GLsizei) target->GetWidth(), (GLsizei) target->GetHeight());

shader->Render(source, target);
}

bool CShaderPresetGL::ReadPresetFile(const std::string& presetPath)
{
return CServiceBroker::GetGameServices().VideoShaders().LoadPreset(presetPath, *this);
Expand Down
50 changes: 13 additions & 37 deletions xbmc/cores/RetroPlayer/shaders/windows/ShaderPresetDX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,50 +100,26 @@ bool CShaderPresetDX::RenderUpdate(const CPoint dest[],

PrepareParameters(target, dest);

// At this point, the input video has been rendered to the first texture ("source", not
// m_pShaderTextures[0])

IShader* firstShader = m_pShaders.front().get();
CShaderTextureCD3D* firstShaderTexture = m_pShaderTextures.front().get();
IShader* lastShader = m_pShaders.back().get();

const unsigned passesNum = static_cast<unsigned int>(m_pShaders.size());

if (passesNum == 1)
firstShader->Render(source, target);
else if (passesNum == 2)
// Apply all passes except the last one (which needs to be applied to the backbuffer)
for (unsigned int shaderIdx = 0; shaderIdx < static_cast<unsigned int>(m_pShaders.size()) - 1;
++shaderIdx)
{
// Apply first pass
RenderShader(firstShader, source, firstShaderTexture);

// Apply last pass
RenderShader(lastShader, firstShaderTexture, target);
IShader* shader = m_pShaders[shaderIdx].get();
IShaderTexture* texture = m_pShaderTextures[shaderIdx].get();
RenderShader(shader, source, texture);
source = texture;
}
else
{
// Apply first pass
RenderShader(firstShader, source, firstShaderTexture);

// Apply all passes except the first and last one (which needs to be applied to the backbuffer)
for (unsigned int shaderIdx = 1; shaderIdx < static_cast<unsigned int>(m_pShaders.size()) - 1;
++shaderIdx)
{
IShader* shader = m_pShaders[shaderIdx].get();
CShaderTextureCD3D* prevTexture = m_pShaderTextures[shaderIdx - 1].get();
CShaderTextureCD3D* texture = m_pShaderTextures[shaderIdx].get();
RenderShader(shader, prevTexture, texture);
}
// Restore our viewport
m_context.SetViewPort(viewPort);
m_context.SetScissors(viewPort);

// Apply last pass and write to target (backbuffer) instead of the last texture
CShaderTextureCD3D* secToLastTexture = m_pShaderTextures[m_pShaderTextures.size() - 2].get();
RenderShader(lastShader, secToLastTexture, target);
}
// Apply the last pass and write to target (backbuffer) instead of the last texture
IShader* lastShader = m_pShaders.back().get();
lastShader->Render(source, target);

m_frameCount += static_cast<float>(m_speed);

// Restore our view port.
m_context.SetViewPort(viewPort);

return true;
}

Expand Down

0 comments on commit 3a176c2

Please sign in to comment.