From 3a176c2a90a1f947da2dda0e3866ce46186a46ef Mon Sep 17 00:00:00 2001 From: KOPRajs Date: Sat, 27 Apr 2024 12:00:24 +0200 Subject: [PATCH] Clean up multipass rendering logic --- .../RetroPlayer/shaders/gl/ShaderPresetGL.cpp | 92 +++++++------------ .../shaders/windows/ShaderPresetDX.cpp | 50 +++------- 2 files changed, 45 insertions(+), 97 deletions(-) diff --git a/xbmc/cores/RetroPlayer/shaders/gl/ShaderPresetGL.cpp b/xbmc/cores/RetroPlayer/shaders/gl/ShaderPresetGL.cpp index acbfedb72b9a0..77e19f4aa6f6b 100644 --- a/xbmc/cores/RetroPlayer/shaders/gl/ShaderPresetGL.cpp +++ b/xbmc/cores/RetroPlayer/shaders/gl/ShaderPresetGL.cpp @@ -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) { @@ -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(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(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(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(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(m_speed); return true; } +void CShaderPresetGL::RenderShader(IShader* shader, + IShaderTexture* source, + IShaderTexture* target) const +{ + if (static_cast(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(target)->UnbindFBO(); + } +} + bool CShaderPresetGL::Update() { auto updateFailed = [this](const std::string& msg) @@ -461,16 +443,6 @@ void CShaderPresetGL::PrepareParameters(const IShaderTexture* texture, const CPo m_pShaders.back()->PrepareParameters(m_dest, true, static_cast(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); diff --git a/xbmc/cores/RetroPlayer/shaders/windows/ShaderPresetDX.cpp b/xbmc/cores/RetroPlayer/shaders/windows/ShaderPresetDX.cpp index be61edf651d60..cd901e28bd137 100644 --- a/xbmc/cores/RetroPlayer/shaders/windows/ShaderPresetDX.cpp +++ b/xbmc/cores/RetroPlayer/shaders/windows/ShaderPresetDX.cpp @@ -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(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(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(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(m_speed); - // Restore our view port. - m_context.SetViewPort(viewPort); - return true; }